2009-12-18 1 views
1

Мне показалось странным, что любому классу, который наследует от IEnumerable<T>, не нужно реализовывать Add(T object), хотя если вы хотите использовать collection initializers при инициализации экземпляра класса, вы должны реализовать Add(T object).Добавить (объект T) Не является ли метод контракта IEnumerable <T> - Почему?

Почему это так?

ответ

6

IEnumerable<T> является интерфейсом только для чтения - он предназначен только для представления «последовательности».

Для инициализаторов коллекции требуется Add, но они проверяют, что тип реализует IEnumerable, чтобы убедиться, что это действительно тип коллекции какого-либо описания. Они не требуют общей формы, так как это будет ограничивать некоторый код до 2.0 (в частности, различные коллекции пользовательского интерфейса не реализуют IEnumerable<T> IIRC), и они не требуют конкретныхAdd подписи, поскольку могут использоваться инициализаторы коллекции с разным количеством аргументов. Например, Dictionary<TKey, TValue> имеет Add(TKey value, TValue value), так что вы можете использовать:

var dictionary = new Dictionary<string, int> 
{ 
    { "Jon", 33 }, 
    { "Tom", 6 } 
}; 

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

+0

из первоисточника здесь: http://escrow.aliexpress.com : //blogs.msdn.com/madst/archive/2006/10/10/What-is-a-collection_3F00_.aspx – LukeH

+0

Стоит отметить, что 'foreach' использует утиную печать на' IEnumerable', поэтому можно перебирать что-то, используя 'foreach', не имея возможности использовать инициализаторы коллекции на нем. – thecoop

0

Потому что IEnumerable<T> является интерфейсом для , перечислив коллекцию, ничего больше.

От MSDN:

разоблачает нумератор, который поддерживает простой итерации по коллекции из указанного типа.

0

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

0

Я думаю, самая большая причина в том, что не все коллекции должны быть перечислены. Кроме того, тот факт, что вы можете иметь другие элементы, которые перечислены, например, вычисления или какой-либо другой процесс.

Например, вы можете использовать IEnumerable с помощью команды Yield для вычисления простых чисел или последовательности фибоначчи. Это действительно зависит от вас.

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

Мои два цента.

+0

Более убедительная причина заключается в том, что не все перечисления должны быть коллекциями. – erikkallen

2

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

Ваш широкий вопрос о том, почему коллекция инициализаторов требует сочетания IEnumerable и Add метод, вероятно, best addressed by Mads Torgersen:

Что такое коллекция?

Что же мы нашли? Только 14 из наших классов (с общественностью ) используют ICollection<T>! Очевидно, что в рамке больше коллекций, , поэтому было ясно, что нам нужен был какой-то другой способ сказать, что-то - это класс коллекции. LINQ к спасения еще раз: с измененными версий запроса это было легко установить, что среди наших общественных классов с государственными конструкторами там являются:

  • 189, которые имеют публичный Add метод и реализовать System.Collections.IEnumerable

  • 42, которые имеют публичный Add метод, но не реализуют System.Collections.IEnumerable

Если посмотреть на классы, возвращенных этих двух запросов, вы понимаете, что есть по существу два принципиально разные значения название «Добавить»:

а) Вставьте аргумент в корзину , или

b) Возвращает арифметическую сумму аргумента и приемника.

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

Коллекция представляет собой тип, который реализует IEnumerable и имеет публичный Add метод

 Смежные вопросы

  • Нет связанных вопросов^_^