C# 为什么ICollection不包含Add方法?

C# 为什么ICollection不包含Add方法?,c#,.net,api-design,C#,.net,Api Design,如标题所示,有人知道为什么ICollection接口不包含Add方法吗?通用版本,ICollection有一个Add,但ICollection没有,这似乎很奇怪。任何对此有深入了解的人都会非常有帮助 至于我为什么关心这个问题——不幸的是,构建SharePoint的开发人员从未学习过泛型,因此API中的每个集合都是基于ICollection的非泛型集合。我想将几个扩展方法附加到ICollection,其中包括添加到集合中,但这似乎是不可能的(至少在没有反射的情况下是不可能的) 编辑: 很多人猜测原

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

至于我为什么关心这个问题——不幸的是,构建SharePoint的开发人员从未学习过泛型,因此API中的每个集合都是基于
ICollection
的非泛型集合。我想将几个扩展方法附加到
ICollection
,其中包括添加到集合中,但这似乎是不可能的(至少在没有反射的情况下是不可能的)

编辑:

很多人猜测原因是因为
ICollection.Add
需要一个
对象,因此不会是类型安全的。事实并非如此
IList
有一个采用
对象的
Add
方法。您只需在接受
对象的方法中执行类型检查和强制转换

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

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

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


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

在我看来,接口的命名似乎混淆了预期
ICollection
ICollection
甚至不在同一继承链中-大多数集合只是简单地实现了两者

文档说明了接口的功能,因此仅凭此一点,就不可能存在
Add

定义所有对象的大小、枚举数和同步方法 非属收藏

我怎么想?我个人认为这要么是一个直接的命名错误,要么是第二次(在引入通用接口时),设计师选择将
Add
放在
ICollection
中,因为这一次需要它更为常见

IList
Add
和继承
ICollection
,而
IList
没有
Add
和继承
ICollection
,这与
Add
一样

将其归因于类型层次结构设计的演变/成熟。
对于扩展方法,您可以执行以下操作:

public static void AnotherMethod<T>(this ICollection<T> collection, T item) { }
publicstaticvoidanothermethod(此ICollection集合,T项){}
这样使用它:

ICollection<string> s;
s.AnotherMethod("");
ICollection s;
s、 无热法(“”);
基于

定义所有对象的大小、枚举数和同步方法 非属集合

这意味着ICollection表示要读取的数据流或数据序列。
我想说的是,
sharepointapi
背后的决策可能是提供从服务器读取的通用数据流

一个猜测是,如果
ICollection
确实有
Add
方法,那么需要什么<代码>对象
当然。这对于C#2.0之前的通用数组来说是个大问题


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

i集合
可以是任何内容。它可能只是可枚举的东西。没有理由存在一个
Add
方法,或者确实存在一个
Remove
。如果您更仔细地观察界面,它几乎是只读的。您可以看到有多少个元素,并可以枚举它们。就这样。这在某种程度上是非常有意义的

当我们谈到
ICollection
时,我们现在是非常具体的。我们确切地知道它持有什么样的物体,因此我们可以:

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

本质上,区别在于,
ICollection
有些具体。

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

当创建
ICollection
时,没有泛型接口。这意味着,如果在
ICollection
上有
Add
方法,则必须有签名
Add(object)
ICollection
旨在跨任何类型的集合声明一个一致的接口——这将迫使每个集合部分地执行类似于
对象的集合的操作

这已在
ICollection
中修复,它有一个方法
Add(T)

根据

通用版本和非通用版本在以上方面有所不同 您可能期望的,特别是在ICollection的情况下

原因主要是历史原因:be