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