在 .NET 4.5/C# 5 中,IReadOnlyCollection<T>
声明为Count
财产:
public interface IReadOnlyCollection<out T> : IEnumerable<T>, IEnumerable
{
int Count { get; }
}
我想知道,这是否有意义ICollection<T>
实施IReadOnlyCollection<T>
界面还有:
public interface ICollection<T> : IEnumerable<T>, IEnumerable, *IReadOnlyCollection<T>*
这意味着类实现ICollection<T>
会自动实现IReadOnlyCollection<T>
。这对我来说听起来很合理。
The ICollection<T>
抽象可以被看作是IReadOnlyCollection<T>
抽象。注意List<T>
,例如,同时实现ICollection<T>
and IReadOnlyCollection<T>
.
然而它并不是这样设计的。
我在这里缺少什么?为什么会选择当前的实现?
UPDATE
我正在寻找一个使用的答案面向对象的设计推理解释一下原因:
- 一个具体的类,例如
List<T>
实施两者IReadOnlyCollection<T>
and ICollection<T>
是一个比以下更好的设计:
-
ICollection<T>
实施IReadOnlyCollection<T>
直接地
另请注意,这本质上是同一个问题:
- 为什么不
IList<T>
实施IReadOnlyList<T>
?
- 为什么不
IDictionary<T>
实施IReadOnlyDictionary<T>
?
可能有几个原因。这里有一些:
-
巨大的向后兼容性问题
你会如何写出 的定义ICollection<T>
?这看起来很自然:
interface ICollection<T> : IReadOnlyCollection<T>
{
int Count { get; }
}
但它有一个问题,因为IReadOnlyCollection<T>
还声明了一个Count
属性(编译器将在此处发出警告)。除了警告之外,保持原样(相当于编写new int Count
)允许实现者有不同的两者的实现Count
通过显式实现至少一个属性。如果两个实现决定返回不同的值,这可能会“有趣”。让人们搬起石头砸自己的脚,这可不是 C# 的风格。
好的,那怎么样:
interface ICollection<T> : IReadOnlyCollection<T>
{
// Count is "inherited" from IReadOnlyCollection<T>
}
好吧,这破坏了决定实现的所有现有代码Count
明确地:
class UnluckyClass : ICollection<Foo>
{
int ICollection<Foo>.Count { ... } // compiler error!
}
因此,在我看来,这个问题没有好的解决方案:要么破坏现有代码,要么强制执行容易出错的实现everyone. So 唯一的胜利之举就是不玩 https://www.google.com/search?q=the%20only%20winning%20move%20is%20not%20to%20play.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)