首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么泛型ICollection不在.NET 4.5中实现IReadOnlyCollection?

为什么泛型ICollection不在.NET 4.5中实现IReadOnlyCollection?
EN

Stack Overflow用户
提问于 2012-09-27 13:28:22
回答 5查看 10.5K关注 0票数 64

在.NET 4.5 / C# 5中,使用Count属性声明IReadOnlyCollection<T>

代码语言:javascript
运行
复制
public interface IReadOnlyCollection<out T> : IEnumerable<T>, IEnumerable
{
    int Count { get; }
}

我想知道,对于ICollection<T>来说,实现IReadOnlyCollection<T>接口是否也是有意义的:

代码语言:javascript
运行
复制
public interface ICollection<T> : IEnumerable<T>, IEnumerable, *IReadOnlyCollection<T>*

这意味着实现ICollection<T>的类将自动实现IReadOnlyCollection<T>。这在我看来是合理的。

ICollection<T>抽象可以看作是IReadOnlyCollection<T>抽象的扩展。注意,例如,List<T>实现了ICollection<T>IReadOnlyCollection<T>

然而,它的设计并不是那样的。

我在这里错过了什么?为什么要选择当前的实现呢?

更新

我正在寻找一个使用面向对象设计推理来解释原因的答案:

  • 一个具体的类,如List<T>,实现了IReadOnlyCollection<T>ICollection<T>

比以下设计更好:

  • ICollection<T>直接实现IReadOnlyCollection<T>

此外,请注意,这基本上与以下问题相同:

  1. 为什么IList<T>不实现IReadOnlyList<T>
  2. 为什么IDictionary<T>不实现IReadOnlyDictionary<T>
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2013-02-18 20:04:42

乔恩就在这里,https://stackoverflow.com/a/12622784/395144,你应该把他的回答标记为:

代码语言:javascript
运行
复制
int ICollection<Foo>.Count { ... } // compiler error!

由于接口可以有显式实现,因此提取基本接口并不是向后兼容的(与基类不存在此问题)。

所以..。

代码语言:javascript
运行
复制
Collection<T> : IReadOnlyCollection<T>
List<T> : IReadOnlyList<T>
Dictionary<TKey, TValue> : IReadOnlyDictionary<TKey, TValue>

..。但不是他们的接口。

IMHO,他们最初做了一个设计错误,现在很难解决(没有破坏)。

编辑:隐藏没有帮助,旧的(显式的)实现仍然不会构建(不修改代码):

代码语言:javascript
运行
复制
interface INew<out T> { T Get(); }

interface IOld<T> : INew<T>
{
    void Set(T value);
    new T Get();
}

class Old<T> : IOld<T>
{
    T IOld<T>.Get() { return default(T); }
    void IOld<T>.Set(T value) { }
}

'Sample.Old‘不实现接口成员'Sample.INew.Get()’

票数 17
EN

Stack Overflow用户

发布于 2012-09-27 13:40:17

可能有几个原因。以下是一些:

  • 巨大的向后兼容性问题 您将如何编写ICollection<T>的定义?这看起来很自然: 接口ICollection : IReadOnlyCollection { int计数{ get;} 但是它有一个问题,因为IReadOnlyCollection<T>还声明了一个Count属性(编译器将在这里发出警告)。除了警告之外,保留原样(相当于编写new int Count)允许实现者至少显式地实现两个Count属性的不同实现。如果这两个实现决定返回不同的值,这可能是“有趣的”。允许人们朝自己的脚开枪并不是C#的风格。 好吧,那么: 接口ICollection : IReadOnlyCollection { // Count是从IReadOnlyCollection }“继承”的 这破坏了所有决定显式实现Count的现有代码: 类UnluckyClass : ICollection { int ICollection.Count {.} //编译器错误!} 因此,在我看来,这个问题没有很好的解决方案:要么破坏现有代码,要么强迫每个人都实现错误。所以唯一获胜的方法就是不玩。
票数 42
EN

Stack Overflow用户

发布于 2012-09-27 13:43:35

这在语义上是错误的,因为显然,并不是每个ICollection都是只读的。

也就是说,他们可以调用接口IReadableCollection,而实现可以称为ReadOnlyCollection

然而,他们没有走那条路。为什么?我看到了一个BCL团队成员写道,他们不希望集合API变得太复杂。(坦率地说,已经是了。)

票数 -2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12622539

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档