共用方式為


使用 Iterator (C# 程式設計手冊)

建立 iterator 最常見的方式,就是實作 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> 介面的泛用 Iterator 之範例,請參閱 HOW TO:建立泛型清單的 Iterator 區塊 (C# 程式設計手冊)

也可以使用具名的 Iterator 來支援逐一查看相同資料集合的不同方式。 例如,您可提供以遞增順序傳回項目的 Iterator,以及以遞減順序傳回項目的 Iterator。 Iterator 也可以擁有參數,讓用戶端可以控制全部或部分的反覆運算行為。 下列 Iterator 使用具名的 Iterator 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;
    }
}

叫用具名 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

您可以在同一個 Iterator 中使用一個以上的 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) 時,下一個 Iterator 程式碼主體會從前一個 yield 陳述式之後繼續執行,並一直重複,直到 Iterator 主體結束或遇到 yield break 陳述式為止。

這些 Iterator 都不支援 IEnumerator.Reset 方法。 若要從頭開始重新執行反覆查看,您必須取得新的 Iterator。

範例

下列程式碼包含本主題中的所有範例。

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 ".";
        }
    }
}

請參閱

工作

HOW TO:建立整數清單的 Iterator 區塊 (C# 程式設計手冊)

HOW TO:建立泛型清單的 Iterator 區塊 (C# 程式設計手冊)

參考

yield (C# 參考)

搭配陣列使用 foreach (C# 程式設計手冊)

foreach、in (C# 參考)

概念

C# 程式設計手冊