2016-12-22 12 views
2

Я изо всех сил стараюсь понять преимущества IEnumerable. Я понимаю, что Enumerables разрешает выполнение отсрочки позже.Преимущество перечислений

См. Пример здесь: https://msdn.microsoft.com/en-us/library/system.collections.ienumerable(v=vs.110).aspx. В этом примере массив уже заполняется в основном классе, а затем вводится в класс IEnumerable. Поэтому это, по-видимому, устраняет преимущество отсрочки исполнения до более позднего времени. Что мне здесь не хватает?

+2

Преимущество в том, что касается * каждого * интерфейса, чтобы обеспечить наименьшую информацию для вызывающего абонента. Поэтому вместо того, чтобы говорить для члена «Мне нужен массив для правильной работы», вы также можете сказать: «Мне нужна какая-то коллекция, которую я могу перечислить». Так что неважно, действительно ли это массив, список или даже en (бесконечный) поток. – HimBromBeere

+2

'IEnumerable ' в первую очередь о возможности повторения итерации через нуль или более экземпляров 'T' - нет ничего скрытого в перечислениях, которые допускают отложенное выполнение. Однако бывает, что LINQ предоставляет набор операторов, которые допускают отсроченное выполнение над перечисляемыми. Это две разные вещи. – Enigmativity

ответ

2

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

Образец полезен в лучшем случае, чтобы показать, как пользовательский тип может действовать как коллекция, реализуя IEnumerable. Разумеется, этот общий интерфейс может быть вызван из разных мест, где вам не нужны конкретные знания о типе коллекции, но это не показано в примере.

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

+0

Есть ли лучший пример, который вы можете порекомендовать, который показывает, как его можно использовать более эффективно? Спасибо – w0051977

+0

Возможно [эта документация на 'yield return'] (https://msdn.microsoft.com/en-us/library/9k7k7cf0.aspx), но нет другого источника, о котором я могу сейчас думать. –

+0

Напоминание ключевого слова Yield (что-то, что я не использовал некоторое время) было полезным здесь. Если что-то будет действовать как коллекция, то это наверняка должна быть коллекция? – w0051977

0

Это выбор дизайна, следует ли отложить оценку или нет, но не имеет права IEnumerable. Некоторые выходные запросы Linq (например, Where &) отложите оценку, другие коллекции, такие как Dictionary или List, не используют.

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

Предположим, вы хотите реализовать метод ToString для общей коллекции, где у объекта есть собственный ToString. Если вы принимаете IEnumerable вместо массива, List или Set можно передать как аргумент без каких-либо изменений кода.

4

Основная цель IEnumerable: не отложить исполнение до более позднего срока. Целью IEnumerable является предоставление способа итерации по частям объекта. Эти части могут быть элементами списка, но они также могут быть (например) символами string. Интерфейс IEnumerable существует, потому что не каждый класс, который допускает итерацию по его частям, представляет собой коллекцию или список (например, string) и IEnumerable, обеспечивает минимальный интерфейс для достижения этого без необходимости выполнять полностью взорванный ICollection или IList.

Основным и наиболее важным потребителем в IEnumerable является foreach утверждение, которое существует с начала времени .NET. Только позже появился LINQ с классом Enumerable, который также основывается на интерфейсе IEnumerable (или, точнее, на IEnumerable<T>).

Говоря о LINQ, отсроченное выполнение, которое вы ссылаетесь в своем вопросе, действительно является ключевой особенностью LINQ. Это означает, что запрос, который вы определяете, не выполняется до тех пор, пока не будет выполнена итерация IEnumerable. Это позволяет вам доработать ваши запросы перед их выполнением.

Это отложенное исполнение, хотя относится только к какIEnumerableиспользуется, не то, что он делает. Отложенное выполнение означает, что вы не начнете перебрать IEnumerable при определении его, но в другом месте в программе, например, foreach, ToList и т.д.

+2

Я не уверен, что 'string' - очень хороший контрпример. «Строка» - это не что иное, как массив 'char'. В противном случае вы остаетесь на все остальное. – gmiley

+0

@gmiley - Вот что говорит Sefe. Он указывает, что 'string' является перечислимым символом' char'. Он прав. – Enigmativity

+1

@gmiley: Строка на самом деле не совпадает с массивом символов (даже если внутреннее хранилище находится в 'char []'). Главное отличие состоит в том, что 'char []' является 'IList', а' string' - нет. Вот почему я выбрал этот пример, потому что 'string' - _only_' IEnumerable', даже не 'ICollection'. – Sefe

1

Одним из примеров IEnumerable запаздывает выполнение.

я вещь, что BIGS преимущество использования IEnumerable являются:

  1. Вы можете перебирать коллекцию, не зная, как перебрать его (это коллекция есть индексатор Как я итерацию Дерево? и т.д.).

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

  3. Позднее исполнение - вы можете фильтровать коллекции, и реальная фильтрация будет происходить, как только вы пройдете свой IEnumerable (используя ForEach \ ToList и т. Д.).

+0

@HimBromBeere Nope. Но прежде чем вы имели интерфейс IEnumerable, вам нужно было знать, как выполнять итерации коллекций и других классов, которые являются перечисляемыми. –

+1

Полиморфизм важен. Поэтому +1 для первой. – w0051977