为什么IEnumerable <t>没有实现Add(T)?</t>

时间:2010-08-27 08:00:40

标签: c# .net generics collections ienumerable

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

6 个答案:

答案 0 :(得分:48)

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

答案 1 :(得分:11)

IEnumerable用于阅读,而不是用于写作。

答案 2 :(得分:10)

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

能够枚举对于许多类型的对象是通用的。例如,它由数组和集合共享。但是你不能在没有弄乱它的结构的情况下“添加”一个数组 - 而一个Collection是专门为了添加和删除而构建的。

从技术上讲,你可以'添加'到一个可枚举的,但是 - 使用Concat<> - 但是所有这一切都是创建一个枚举器,枚举从一个可枚举到下一个 - 给出一个有意义的集合的幻觉。 / p>

答案 3 :(得分:3)

每个ICollection应该是IEnumerable(我认为,.NET Framework团队似乎同意我;-)),但反过来并不总是有意义的。在这个世界中存在“像对象一样的集合”的层次结构,并且假设可枚举将是可以添加项目的集合在该层次结构中不成立。

示例:主要颜色名称列表将是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";
}

答案 4 :(得分:2)

正如其名称所示,您可以枚举(循环)IEnumerable,这就是它。 如果你想能够添加一些东西,它就不再只是一个可枚举的东西了,因为它有额外的功能。

例如,数组是IEnumerable,但数组具有固定长度,因此您无法向其中添加新项。

IEnumerable只是所有类型集合的“基础”(甚至只读集合 - 显然没有Add()方法)。 您添加到这种“基本界面”的功能越多,它就越具体。

答案 5 :(得分:2)

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