为什么 ICollection 不包含 Add 方法

本文关键字:Add 方法 包含 ICollection 为什么 | 更新日期: 2024-07-27 05:46:53

如标题所示,有谁知道为什么ICollection接口不包含 Add 方法?通用版本ICollection<T> 有一个AddICollection没有,这似乎很奇怪。任何对此有更深入了解的人都会非常有帮助。

至于我为什么关心 - 不幸的是,构建 SharePoint 的开发人员从未了解泛型,因此 API 中的每个集合都是基于 ICollection 的非泛型集合。我想将几个扩展方法附加到涉及添加到集合等ICollection,但这似乎是不可能的(至少没有反射是不可能的(。

编辑:

相当多的人猜测原因是因为ICollection.Add需要一个Object,因此不会是类型安全的。事实并非如此。 IList有一个Add方法,需要Object。您只需要在需要Object的方法中进行类型检查和强制转换。

数组实现ICollection因此不能有Add的论点也站不住脚。如果ICollection有一个Add方法,它只需要在数组上显式实现并抛出异常(就像数组当前实现的许多方法一样(。

我真的希望有人能参考其中一位设计师的解释。

为什么 ICollection 不包含 Add 方法

对我来说,接口的命名似乎混淆了期望。 ICollectionICollection<T> 甚至不在同一继承链中 - 大多数集合只是简单地实现两者。

文档说明了接口的作用,因此仅凭这一点,人们就不会期望Add存在:

定义所有大小、枚举器和同步方法 非泛型集合。

我怎么看?我个人认为这要么是直接命名 gaff,要么是第二次(在引入通用接口时(设计师选择Add放在ICollection<T>中,因为这次需要它更常见。

IListAdd并继承ICollectionIList<T>没有Add并继承ICollection<T>,如Add

将其

粉笔化为类型层次结构设计的演变/成熟。


至于扩展方法,您可以执行以下操作:
public static void AnotherMethod<T>(this ICollection<T> collection, T item) { }

并因此使用它:

ICollection<string> s;
s.AnotherMethod("");

创建ICollection时,没有通用接口。 这意味着,如果ICollection上有Add方法,则必须具有签名Add(object)ICollection 旨在跨任何类型的集合声明一致的接口 - 这将强制每个集合部分地操作,就像 object 的集合一样。

这已在方法Add(T) ICollection<T>中修复。

ICollection可以是任何东西。 它可能只是可枚举的东西。 没有理由应该有一个Add的方法,或者实际上是一个Remove。 如果你更仔细地看界面,它几乎是只读的。 您可以看到有多少元素,并且可以枚举它们。 就是这样。 这完全有道理,以一种抽象的方式。

当我们进入ICollection<T>时,我们现在非常具体。 我们确切地知道它包含什么样的对象,因此我们可以:

  • 添加新的<T>元素。
  • 使用IEquitable类型的界面搜索它们。
  • 使用相同的方法删除它们。

从本质上讲,区别在于ICollection<T>有些具体。

根据阿尔巴哈里兄弟的说法

通用版本

和非通用版本在各种方面有所不同 您可能会期望什么,尤其是在ICollection的情况下。

造成这种情况的原因主要是历史的:因为仿制药来了 后来,通用接口被开发出来,其优点是 事后诸葛亮

出于这个原因,

ICollection<T>不延伸ICollection

IList<T>不扩展IList

并且IDictionary<TKey, TValue>不会扩展IDictionary.

总而言之,ICollection<T>已经通过不犯ICollection年所犯的错误而演变。这就是为什么ICollection<T>有一个 Add 方法而ICollection没有。

来自MSDN

当以多态方式代替其他集合或集合接口使用时,不需要将集合类型添加到已知类型。例如,如果声明 IEnumerable 类型的数据成员并使用它来发送 ArrayList 的实例,则无需将 ArrayList 添加到已知类型。

以多态方式使用集合代替非集合类型时,必须将它们添加到已知类型中。例如,如果声明 Object 类型的数据成员并使用它来发送 ArrayList 的实例,请将 ArrayList 添加到已知类型。

根据 Msdn 的定义,它是

定义所有大小、枚举器和同步方法 非泛型集合

这意味着 ICollection 呈现您将要读取的数据流数据序列。我想说的是,SharePoint API背后的决策可能是提供您从服务器读取的通用数据流

有人猜测,如果ICollection确实有Add方法,那需要什么? 当然Object。对于没有泛型数组来说,这是一个大问题,而在 C# 2.0 之前就有。

问题是您可以向同一集合添加不同的类型

疯狂猜测 - ICollection 接口是扩展它的其他接口的基本接口,例如 IList 和 IDictionary。这些接口具有不同的 add 方法实现。IList需要一个参数,IDictionary显然需要两个参数。对于泛型,派生接口方法签名并没有真正的区别,因为它们需要一个参数 - 一个类型。