简体   繁体   English

为什么不IEnumerable <T> 实现Add(T)?

[英]Why doesn't IEnumerable<T> implement Add(T)?

Just now find it by chance, Add(T) is defined in ICollection<T> , instead of IEnumerable<T> . 刚刚发现它,Add(T)在ICollection<T>定义,而不是IEnumerable<T> And extension methods in Enumerable.cs don't contain Add(T), which I think is really weird. Enumerable.cs中的扩展方法不包含Add(T),我认为这很奇怪。 Since an object is enumerable, it must "looks like" a collection of items. 由于对象是可枚举的,因此它必须“看起来像”一组项目。 Can anyone tell me why? 谁能告诉我为什么?

An IEnumerable<T> is just a sequence of elements; IEnumerable<T>只是一系列元素; see it as a forward only cursor. 将其视为仅向前游标。 Because a lot of those sequences are generating values, streams of data, or record sets from a database, it makes no sense to Add items to them. 因为很多这些序列正在从数据库生成值,数据流或记录集,所以向它们Add项是没有意义的。

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

An enumerable is exactly that - something you can enumerate over and discover all the items. 可枚举就是这样 - 你可以枚举并发现所有项目。 It does not imply that you can add to it. 这并不意味着您可以添加它。

Being able to enumerate is universal to many types of objects. 能够枚举对于许多类型的对象是通用的。 For example, it is shared by arrays and collections. 例如,它由数组和集合共享。 But you can't 'add' to an array without messing about with it's structure - whereas a Collection is specifically built to be added to and removed from. 但是你不能在没有弄乱它的结构的情况下“添加”数组 - 而集合是专门为了添加和删除而构建的。

Technically you can 'add' to an enumerable, however - by using Concat<> - however all this does is create an enumerator that enumerates from one enumerable to the next - giving the illusion of a single contigious set. 从技术上讲,你可以通过使用Concat<>来“添加”一个枚举,但是所有这一切都是创建一个枚举器,枚举从一个可枚举到下一个 - 给出一个单一的可以设置的错觉。

Each ICollection should be IEnumerable (I think, and the .NET Framework team seems to agree with me ;-)), but the other way around does not always make sense. 每个ICollection应该是IEnumerable (我认为,.NET Framework团队似乎同意我;-)),但反过来并不总是有意义。 There is a hierarchy of "collection like objects" in this world, and your assumption that an enumerable would be a collection you can add items to does not hold true in that hierarchy. 在这个世界中存在“像对象一样的集合”的层次结构,并且您假设可枚举将是可以添加项目的集合在该层次结构中不成立。

Example: a list of primary color names would be an IEnumerable returning "Red" , "Blue" and "Green" . 示例:主要颜色名称列表将是IEnumerable返回"Red""Blue""Green" It would make no logical sense at all to be able to do a primaryColors.Add("Bright Purple") on a "collection" filled like this: 在这样填充的“集合”上执行primaryColors.Add("Bright Purple")根本没有逻辑意义:

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

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

As its name says, you can enumerate (loop) over an IEnumerable, and that's about it. 正如其名称所示,您可以枚举(循环)IEnumerable,这就是它。 When you want to be able to Add something to it, it wouldn't be just an enumerable anymore, since it has extra features. 当你想能够添加一些东西时,它不再只是一个可枚举,因为它有额外的功能。

For instance, an array is an IEnumerable, but an array has a fixed length, so you can't add new items to it. 例如,数组是IEnumerable,但数组具有固定长度,因此您无法向其中添加新项。

IEnumerable is just the 'base' for all kind of collections (even readonly collections - which have obviously no Add() method). IEnumerable只是所有类型集合的“基础”(甚至只读集合 - 显然没有Add()方法)。 The more functionality you'd add to such 'base interface', the more specific it would be. 您添加到这种“基本界面”的功能越多,它就越具体。

The name says it all. 这个名字说明了一切。 IEnumerable is for enumerating items only. IEnumerable仅用于枚举项目。 ICollection is the actual collection of items and thus supports the Add method. ICollection是项目的实际集合,因此支持Add方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM