为什么通用 ICollection 不在 .NET 4.5 中实现 IReadOnlyCollection?

2024-01-07

在 .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>直接地

另请注意,这本质上是同一个问题:

  1. 为什么不IList<T>实施IReadOnlyList<T>?
  2. 为什么不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(使用前将#替换为@)

为什么通用 ICollection 不在 .NET 4.5 中实现 IReadOnlyCollection? 的相关文章

随机推荐