反復子の使用 (C# プログラミング ガイド)

反復子を作成する場合、次のように IEnumerable インターフェイスで GetEnumerator メソッドを実装するのが最も一般的な方法です。

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

GetEnumerator メソッドが存在するため、型は列挙型になり、foreach ステートメントを使用できます。 上記のメソッドが ListClass のクラス定義の一部である場合、次のようにクラスで foreach を使用できます。

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

    foreach (int i in listClass1)
    {
        System.Console.Write(i + " ");
    }
    // Output: 0 1 2 3 4 5 6 7 8 9
}

foreach ステートメントは ListClass.GetEnumerator() を呼び出し、返された列挙子を使用して、値を反復処理します。 IEnumerator<T> インターフェイスを返すジェネリック反復子を作成する方法の例については、「方法: ジェネリック リストの反復子ブロックを作成する (C# プログラミング ガイド)」を参照してください。

同じデータ コレクションを反復処理する別の方法をサポートするために、名前付き反復子を使用することもできます。 たとえば、要素を昇順で返す反復子と、降順で返す反復子を作成できます。 また、反復動作の全部または一部をクライアントが制御できるようにするパラメーターを反復子に設定することもできます。 次の反復子は、名前付き反復子 SampleIterator を使用して IEnumerable インターフェイスを実装します。

// 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.Write(n + " ");
}
// Output: 1 2 3 4 5 6 7 8 9 10

次のように、同じ反復子で複数の 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);
}
// Output: With an iterator, more than one value can be returned.

この例を実行すると、次のテキストが表示されます。

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

foreach ループを反復するごとに (または IEnumerator.MoveNext を直接呼び出すと)、前の yield ステートメントの後で次の反復子コード本体が再開され、反復子本体の最後に到達するか、または yield break ステートメントに達するまで、このプロセスが継続されます。

反復子は、IEnumerator.Reset メソッドをサポートしません。 反復処理を最初から再度行う場合は、新しい反復子を取得する必要があります。

使用例

次のコードには、このトピックのすべての例が含まれています。

namespace UsingIterators
{
    class Program
    {
        static void Main()
        {
            // Using a simple iterator.
            ListClass listClass1 = new ListClass();

            foreach (int i in listClass1)
            {
                System.Console.Write(i + " ");
            }
            // Output: 0 1 2 3 4 5 6 7 8 9
            System.Console.WriteLine();


            // Using a named iterator.
            ListClass test = new ListClass();

            foreach (int n in test.SampleIterator(1, 10))
            {
                System.Console.Write(n + " ");
            }
            // Output: 1 2 3 4 5 6 7 8 9 10
            System.Console.WriteLine();


            // Using multiple yield statements.
            foreach (string element in new TestClass())
            {
                System.Console.Write(element);
            }
            // Output: With an iterator, more than one value can be returned.
            System.Console.WriteLine();

        }
    }

    class ListClass : System.Collections.IEnumerable
    {

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

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

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

参照

処理手順

方法 : 整数リストの反復子ブロックを作成する (C# プログラミング ガイド)

方法: ジェネリック リストの反復子ブロックを作成する (C# プログラミング ガイド)

参照

yield (C# リファレンス)

配列での foreach の使用 (C# プログラミング ガイド)

foreach、in (C# リファレンス)

概念

C# プログラミング ガイド