Использование итераторов (Руководство по программированию в C#)

Обновлен: Ноябрь 2007

Наиболее простой способ создания итератора заключается в реализации метода GetEnumerator для интерфейса IEnumerable, например:

public System.Collections.IEnumerator GetEnumerator()
{
    for (int i = 0; i < 10; i++)
    {
        yield return i;
    }
}

Наличие метода GetEnumerator создает тип перечисляемого типа и позволяет использовать оператор foreach statement. Если бы приведенный выше метод был частью определения класса для ListClass, то можно было бы использовать foreach для класса следующим образом:

static void Main()
{
    ListClass listClass1 = new ListClass();

    foreach (int i in listClass1)
    {
        System.Console.WriteLine(i);
    }
}

Оператор foreach вызывает ListClass.GetEnumerator() и использует возвращенный перечислитель для итерации значений. Пример создания универсального итератора, возвращающего интерфейс IEnumerator<T>, см. в разделе Практическое руководство. Создание блока итератора для общего списка (руководство по программированию в C#).

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

// Implementing the enumerable pattern
public System.Collections.IEnumerable SampleIterator(int start, int end)
{
    for (int i = start; i <= end; i++)
    {
        yield return i;
    }
}

Именованный итератор вызывается следующим образом.

ListClass test = new ListClass();
foreach (int n in test.SampleIterator(1, 10))
{
    System.Console.WriteLine(n);
}

В одном итераторе можно использовать несколько операторов yield, как в следующем примере.

public System.Collections.IEnumerator GetEnumerator()
{
    yield return "With an iterator, ";
    yield return "more than one ";
    yield return "value can be returned";
    yield return ".";
}

Результаты можно вывести с помощью оператора foreach.

foreach (string element in new TestClass())
{
    System.Console.Write(element);
}

В этом примере приведен следующий текст.

With an iterator, more than one value can be returned.

В каждой последовательной итерации цикла foreach (или прямом вызове IEnumerator.MoveNext) следующий текст кода итератора возобновляется после оператора yield и продолжается до конца текста итератора или до оператора yield break.

Итераторы не поддерживают метод IEnumeratorReset(). Для повторной итерации сначала необходимо получить новый итератор.

См. также

Задачи

Практическое руководство. Создание блока итератора для списка целых чисел (Руководство по программированию в C#)

Практическое руководство. Создание блока итератора для общего списка (руководство по программированию в C#)

Основные понятия

Руководство по программированию в C#

Ссылки

yield (справочник по C#)

Использование оператора foreach с массивами (Руководство по программированию на C#)

foreach, in (Справочник по C#)