TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.76K subscribers
Post #384 957
День триста двадцать шестой. #DesignPatterns
Паттерны проектирования
4. Паттерн «Итератор» (Iterator).
Практически любое приложение в той или иной мере работает с коллекциями данных. В некоторых случаях для обработки данных коллекции используется специфический интерфейс конкретных коллекций, но в большинстве случаев доступ к элементам осуществляется через специальный абстрактный слой — итератор.
Назначение: Итераторы предоставляют абстрактный интерфейс для доступа к содержимому составных объектов, не раскрывая клиентам их внутреннюю структуру. В результате получается чёткое разделение ответственности: клиенты получают возможность работать с разными коллекциями унифицированным образом, а классы коллекций становятся проще за счёт того, что ответственность за перебор элементов возлагается на отдельную сущность.
Классическая схема паттерна «Итератор» и реализация паттерна в .Net представлены на рисунке ниже:
- Iterator (IEnumerator<T>) — определяет интерфейс итератора. В .Net имеет методы: MoveNext (переход на следующий элемент, возвращает false, если достигнут конец последовательности), Current (возвращает текущий элемент) и Reset (возвращает итератор к началу коллекции, реализуется не всегда).
- Aggregate (IEnumerable<T>) — коллекция, по которой может
перемещаться итератор. В .Net интерфейс имеет единственный метод GetEnumerator для получения экземпляра итератора.
- ConcreteAggregate1 (List<T>) — конкретная реализация коллекции;
- ConcreteIterator (List<T>.Enumerator) — конкретная реализация
итератора для определённой коллекции.
Итераторы в .NET являются однонаправленными и только для чтения. То есть при изменении коллекции последующий вызов MoveNext итератора выбросит InvalidOperationException. По той же причине нельзя изменять элементы коллекции в цикле foreach. Цикл foreach является универсальным инструментом для обработки коллекций/последовательностей. Компилятор преобразует его в (в упрощённом варианте) вызов метода MoveNext и обращение к свойству Current в цикле while. Для поддержки цикла foreach не обязательно наличие интерфейса IEnumerable. Достаточно, чтобы класс коллекции содержал метод GetEnumerator, который будет возвращать тип с методом MoveNext, возвращающим bool, и свойством Current.

Блоки итераторов
Процесс создания итераторов вручную довольно утомителен и включает управление состоянием и перемещением по элементам коллекции при вызове MoveNext. С помощью блока итераторов реализовать итератор существенно проще:
public static IEnumerator<int> CustomArrayIterator(this int[] array) {
foreach (var n in array) { yield return n; }
}
Блок итераторов преобразуется компилятором языка C# в конечный автомат с несколькими состояниями, соответствующими начальному положению итератора (когда он указывает на –1-й элемент), конечному положению (когда итератор прошёл все элементы) и «среднему» положению, при котором он указывает на определённый элемент.
С помощью блока итераторов можно создавать итераторы для своих коллекций, существующих коллекций или вообще для внешних ресурсов, таких как файлы. Для этого достаточно открыть файл в начале метода и возвращать прочитанные блоки данных с помощью yield return.
Итераторы, полученные с помощью блока итераторов, являются «ленивыми»: их тело исполняется не в момент вызова метода, а при переборе элементов с помощью метода MoveNext.
Кроме того, блоки итераторов можно использовать для создания генераторов последовательностей. Например, «бесконечного» генератора чисел Фибоначчи.

Источник: Тепляков С. "Паттерны проектирования на платформе .NET." — СПб.: Питер, 2015. Глава 4.
More from @netdeveloperdiary
  1. Oct 13, 2026День 2813. #ЗаметкиНаПолях #Async Ещё Раз Про Async/Await в C#. Часть 1 1. Почему существу…
  2. Oct 12, 2026День 2812. #Карьера #AI Как Разработчикам Оставаться Полезными, Когда Код Пишет ИИ? По мер…
  3. Oct 11, 2026День 2811. #ВопросыНаСобеседовании Марк Прайс предложил свой набор из 60 вопросов (как тех…
  4. Oct 10, 2026День 2810. #ЧтоНовенького #VSCode Более Быстрый и Лёгкий C# Dev Kit Мы, разработчики, люби…
  5. Oct 9, 2026День 2809. #Карьера 5 Навыков, Которые Помогут Быстрее Стать Сеньором. Окончание Начало 3.…
  6. Oct 8, 2026День 2808. #Карьера 5 Навыков, Которые Помогут Быстрее Стать Сеньором. Начало В ИТ есть се…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →