8

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

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

编辑:

相当多的人猜测原因是因为ICollection.Add需要一个Object,因此不是类型安全的。事实并非如此。IList 一个Add采用Object. 您只需要在采用Object.

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

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

4

8 回答 8

2

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

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

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

我怎么看?就我个人而言,我认为这要么是直接命名错误,要么是设计师第二次(在引入通用接口时)选择放入AddICollection<T>因为这一次更常见的是需要它。

有和继承,而IList没有和继承,如.AddICollectionIList<T>AddICollection<T>Add

将其归结为类型层次结构设计的演变/成熟。


至于扩展方法,您可以执行以下操作:

public static void AnotherMethod<T>(this ICollection<T> collection, T item) { }

并这样使用它:

ICollection<string> s;
s.AnotherMethod("");
于 2012-07-27T14:51:16.127 回答
1

根据阿尔巴哈里兄弟

泛型和非泛型版本的差异超出了您的预期,尤其是在 ICollection 的情况下。

造成这种情况的原因主要是历史原因:因为泛型出现较晚,所以泛型接口是在 事后诸葛亮的情况下开发的。

为此原因,

ICollection<T>不延长ICollection

IList<T>不延长IList

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

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

于 2012-07-27T15:36:10.957 回答
1

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

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

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

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

于 2012-07-27T14:53:17.067 回答
0

来自MSDN

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

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

于 2012-07-27T14:50:45.497 回答
0

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

于 2012-07-27T14:54:23.220 回答
0

根据Msdn 定义,它是

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

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

于 2012-07-27T14:51:30.443 回答
0

一种猜测是,如果ICollection确实有这种Add方法,它会采取什么措施?Object当然。这是在 C# 2.0 之前没有泛型数组的一个大问题。

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

于 2012-07-27T14:51:55.153 回答
0

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

这已经修复在ICollection<T>其中有一个方法Add(T)

于 2012-07-27T14:55:30.637 回答