Почему IEnumerable <T>не реализует Add (T)? - PullRequest
12 голосов
/ 27 августа 2010

Просто найдите его случайно, добавьте (T) в ICollection<T> вместо IEnumerable<T>. А методы расширения в Enumerable.cs не содержат Add (T), что, на мой взгляд, очень странно. Поскольку объект перечислим, он должен «выглядеть» как коллекция элементов. Может кто-нибудь сказать мне, почему?

Ответы [ 6 ]

48 голосов
/ 27 августа 2010

An IEnumerable<T> - это просто последовательность элементов;видеть его как курсор только вперед.Поскольку многие из этих последовательностей генерируют значения, потоки данных или наборы записей из базы данных, нет смысла Add элементов к ним.

11 голосов
/ 27 августа 2010

IEnumerable для чтения, а не для записи.

10 голосов
/ 27 августа 2010

Перечисляемое - это как раз то, что вы можете перечислить и обнаружить все предметы.Это не означает, что вы можете добавить к нему.

Возможность перечисления универсальна для многих типов объектов.Например, он используется массивами и коллекциями.Но вы не можете «добавить» массив, не поразившись с его структурой - тогда как коллекция специально создана для добавления и удаления из нее.

Технически вы можете «добавить» перечислимое, однако -используя Concat<> - однако все, что это делает, - это создает перечислитель, который перечисляет от одного перечислимого к следующему, - создавая иллюзию единственного константного множества.

3 голосов
/ 27 августа 2010

Каждый 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";
}
2 голосов
/ 27 августа 2010

Название говорит само за себя. IEnumerable предназначен только для перечисления элементов. ICollection представляет собой фактическую коллекцию элементов и поэтому поддерживает метод Add.

2 голосов
/ 27 августа 2010

Как следует из его названия, вы можете перечислять (цикл) через IEnumerable, и это все.Если вы хотите иметь возможность что-то добавить к нему, это больше не будет просто перечислимым, поскольку у него есть дополнительные функции.

Например, массив - это IEnumerable, но массив имеет фиксированную длину, поэтому вы не можете добавлять в него новые элементы.

IEnumerable - это просто «база» для всех видов коллекций (даже коллекций только для чтения - которые, очевидно, не имеют метода Add ()).Чем больше функциональности вы добавите к такому «базовому интерфейсу», тем более конкретным он будет.

...