Подтвердить что ты не робот

Почему IEnumerable <T> не реализует Add (T)?

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

4b9b3361

Ответ 1

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

Ответ 2

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

Ответ 3

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

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

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

Ответ 4

Каждый 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";
}

Ответ 5

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

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

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

Ответ 6

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