2010-08-27 75 views
12

刚才发现偶然,Add(T)定义在ICollection<T>中,而不是IEnumerable<T>。 Enumerable.cs中的扩展方法不包含Add(T),我认为这很奇怪。由于对象是可枚举的,它必须“看起来像”一组项目。谁能告诉我为什么?为什么IEnumerable <T>实现Add(T)?

+0

当初的IEnumerable''需要'来实现Add',会有更多的问题其他方式:*为什么'IEnumerable '有'Add' *。它的方式是非常有用的:) – nawfal 2014-06-08 08:17:59

回答

45

一个IEnumerable<T>只是一个元素序列;将其视为仅前向游标。因为很多这些序列都是从数据库中生成值,数据流或记录集,所以Add项对它们没有任何意义。

+9

+1使用单词*序列*,因为IEnumerable恰好是,而不是某种集合。 – OregonGhost 2010-08-27 08:14:22

+5

downvoters可以解释他们为什么downvoted? – Steven 2012-04-18 18:10:05

11

IEnumerable是供阅读,而不是写作。

2

顾名思义,你可以通过IEnumerable枚举(循环),就是这样。 当你想添加一些东西时,它不会只是一个枚举,因为它有额外的功能。例如,一个数组是一个IEnumerable,但是一个数组的长度是固定的,所以你不能向它添加新的项目。我们可以使用IEnumerable作为所有类型集合的基础(甚至只读集合 - 显然没有Add()方法)。 您将添加到这种“基础接口”的功能越多,它就越具体。

10

一个枚举就是这样 - 你可以枚举并发现所有项目。这并不意味着你可以添加到它。

能够枚举对于许多类型的对象是通用的。例如,它由数组和集合共享。但是你不能'添加'到一个数组而不会搞乱它的结构 - 而一个Collection是专门构建的添加和删除。

然而,从技术上讲,你可以通过使用Concat<>来添加一个枚举值,但是所有这些都会创建一个从枚举值枚举到下一值枚举值的枚举值 - 给出单个连续集的错觉。

+0

+1表示可选的Concat。 – Emile 2010-08-27 12:02:47

2

名称说明了一切。 IEnumerable仅用于枚举项目。 ICollection是项目的实际集合,因此支持Add方法。

3

每个ICollection应该是IEnumerable(我认为,和.NET框架团队似乎同意我;-)),但其他方式并不总是有意义的。在这个世界中存在一个“类似集合的对象”的层次结构,并且假定一个可枚举集合是一个可以添加项目的集合,在该层次结构中不成立。

示例:原色名称列表将为IEnumerable返回"Red","Blue""Green"。这也就没有什么逻辑意义的是能够在充满这样的“收藏”做一个primaryColors.Add("Bright Purple")

...whatever... 
{ 
    ... 
    var primaryColors = EnumeratePrimaryColors(); 
    ... 
} 

private static IEnumerable<string> EnumeratePrimaryColors() { 
    yield return "Red"; 
    yield return "Blue"; 
    yield return "Green"; 
} 
+0

'ICollection'继承自'IEnumerable'并且'ICollection '继承自'IEnumerable '(它继承自IEnumerable')。换句话说,你是对的:每个'ICollection'都是'IEnumerable'。 – Steven 2010-08-27 08:21:11

+0

@Steven:我知道...... – peSHIr 2010-08-27 08:24:34

相关问题