将接口用作私有成员类型是否有意义?
Does it make sense to use interfaces as type of private members?
当我在 C# 中编写 class 时,我经常不仅在 public API/signatures 中使用接口类型,而且还作为私有成员的类型:
public class Foo {
private readonly IDictionary<string, Bar> m_Bars; // <-- here
public Foo() {
m_Bars = new Dictionary<string, Bar>();
}
}
在某些情况下我不这样做,主要是在我需要公开可变集合的某些ReadOnly
接口变体时。最常见的示例是 List<T>
我想公开为 IReadOnlyCollection<T>
或 IReadOnlyList<T>
;我不能使成员分别成为 ICollection<T>
IList<T>
,因为这些接口没有扩展它们的 IReadOnly
对应 and I'd have to 以使其工作:
public class Foo {
private readonly List<Bar> m_Bars; // <-- not here
public Foo() {
m_Bars = new List<Bar>();
}
public IReadOnlyCollection<Bar> Bars => m_Bars;
}
受保护的实例成员有点介于私有成员和 public API 之间,因此公开接口而不是 classes 的一般好处确实适用。
但是对于私人会员,help/hurt/make有什么区别吗?例如,它是否在每次访问成员时引入额外的类型检查?
视情况而定。如果你在构造函数中创建它,你就知道它已经是什么类型了。当您使用依赖注入时,使用接口可能更有意义,因此您的 class 可以获得不同 class 的实例,并且您不必更改内部实现。在您使用 Dictionary 的情况下,我会保留特定类型主要是因为性能,您可以阅读更多内容 here
[does it make] sense to define a private member as IDictionary<K, V>
instead of Dictionary<K, V>
for example?
接口调用的开销很小,但它的数量级并不适合大多数场景。因此,让我们假设没有性能理由支持具体的 class 而不是接口。
使用more-derivedclass的好处是它有更丰富的API,例如
dictionary.Clear()
更简单,并且可能优于
var keysToRemove = dictionary.Keys.ToList();
foreach (var key in keysToRemove )
{
dictionary.Remove(key);
}
或
dictonary = new Dictionary<TKey,TValue>();
使用界面的好处是以后切换到不同的 IDicionary 时,您永远不必更改代码。
对于fully-encapsulated私人会员来说,福利可能相当low-value。
当我在 C# 中编写 class 时,我经常不仅在 public API/signatures 中使用接口类型,而且还作为私有成员的类型:
public class Foo {
private readonly IDictionary<string, Bar> m_Bars; // <-- here
public Foo() {
m_Bars = new Dictionary<string, Bar>();
}
}
在某些情况下我不这样做,主要是在我需要公开可变集合的某些ReadOnly
接口变体时。最常见的示例是 List<T>
我想公开为 IReadOnlyCollection<T>
或 IReadOnlyList<T>
;我不能使成员分别成为 ICollection<T>
IList<T>
,因为这些接口没有扩展它们的 IReadOnly
对应
public class Foo {
private readonly List<Bar> m_Bars; // <-- not here
public Foo() {
m_Bars = new List<Bar>();
}
public IReadOnlyCollection<Bar> Bars => m_Bars;
}
受保护的实例成员有点介于私有成员和 public API 之间,因此公开接口而不是 classes 的一般好处确实适用。
但是对于私人会员,help/hurt/make有什么区别吗?例如,它是否在每次访问成员时引入额外的类型检查?
视情况而定。如果你在构造函数中创建它,你就知道它已经是什么类型了。当您使用依赖注入时,使用接口可能更有意义,因此您的 class 可以获得不同 class 的实例,并且您不必更改内部实现。在您使用 Dictionary 的情况下,我会保留特定类型主要是因为性能,您可以阅读更多内容 here
[does it make] sense to define a private member as
IDictionary<K, V>
instead ofDictionary<K, V>
for example?
接口调用的开销很小,但它的数量级并不适合大多数场景。因此,让我们假设没有性能理由支持具体的 class 而不是接口。
使用more-derivedclass的好处是它有更丰富的API,例如
dictionary.Clear()
更简单,并且可能优于
var keysToRemove = dictionary.Keys.ToList();
foreach (var key in keysToRemove )
{
dictionary.Remove(key);
}
或
dictonary = new Dictionary<TKey,TValue>();
使用界面的好处是以后切换到不同的 IDicionary 时,您永远不必更改代码。
对于fully-encapsulated私人会员来说,福利可能相当low-value。