为什么 ICollection 不包含 Add 方法
本文关键字:Add 方法 包含 ICollection 为什么 | 更新日期: 2024-07-27 05:46:53
如标题所示,有谁知道为什么ICollection
接口不包含 Add 方法?通用版本ICollection<T>
有一个Add
但ICollection
没有,这似乎很奇怪。任何对此有更深入了解的人都会非常有帮助。
至于我为什么关心 - 不幸的是,构建 SharePoint 的开发人员从未了解泛型,因此 API 中的每个集合都是基于 ICollection
的非泛型集合。我想将几个扩展方法附加到涉及添加到集合等ICollection
,但这似乎是不可能的(至少没有反射是不可能的(。
编辑:
相当多的人猜测原因是因为ICollection.Add
需要一个Object
,因此不会是类型安全的。事实并非如此。 IList
有一个Add
方法,需要Object
。您只需要在需要Object
的方法中进行类型检查和强制转换。
数组实现ICollection
因此不能有Add
的论点也站不住脚。如果ICollection
有一个Add
方法,它只需要在数组上显式实现并抛出异常(就像数组当前实现的许多方法一样(。
我真的希望有人能参考其中一位设计师的解释。
对我来说,接口的命名似乎混淆了期望。 ICollection
和 ICollection<T>
甚至不在同一继承链中 - 大多数集合只是简单地实现两者。
文档说明了接口的作用,因此仅凭这一点,人们就不会期望Add
存在:
定义所有大小、枚举器和同步方法 非泛型集合。
我怎么看?我个人认为这要么是直接命名 gaff,要么是第二次(在引入通用接口时(设计师选择Add
放在ICollection<T>
中,因为这次需要它更常见。
IList
有Add
并继承ICollection
而IList<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显然需要两个参数。对于泛型,派生接口方法签名并没有真正的区别,因为它们需要一个参数 - 一个类型。