简体   繁体   中英

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> . And extension methods in Enumerable.cs don't contain Add(T), which I think is really weird. 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; 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.

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.

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. 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" . It would make no logical sense at all to be able to do a primaryColors.Add("Bright Purple") on a "collection" filled like this:

...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. 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 is just the 'base' for all kind of collections (even readonly collections - which have obviously no Add() method). 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. ICollection is the actual collection of items and thus supports the Add method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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