1. 程式人生 > >C# 使用迭代器實現對自定義類的foreach遍歷

C# 使用迭代器實現對自定義類的foreach遍歷

假設我們實現了一個自定義棧, 需要對其從棧頂到棧底遍歷一遍, 找到需要的元素.

我們可以在類內部提供一個迭代器GetEnumerator , 而不必實現整個 IEnumerable介面. 當編譯器檢測到迭代器時, 它將自動生成 IEnumerable 或 IEnumerable<T>介面的 CurrentMoveNext 和 Dispose 方法.

即類繼承介面IEnumerable, 再提供一個迭代器GetEnumerator就可以了

public IEnumerator GetEnumerator() {
    for (int i = Size-1; i >=0
; i--) { yield return mStackArray[i]; } }

GetEnumerator 方法的存在使得型別成為可列舉的型別,並允許使用 foreach語句, yield 關鍵字向編譯器指示它所在的方法是迭代器塊.  在迭代器塊中,yield關鍵字與return關鍵字結合使用,向列舉器物件提供值, 可以提供在foreach語句的每一次迴圈中返回的值.

我們還可以使用命名的迭代器來實現以不同的方式迴圈訪問同一資料集合. 例如,可以提供一個按升序返回元素的迭代器,和一個按降序返回元素的另一個迭代器. 迭代器還可以帶有引數,以便允許控制全部或部分迭代行為.

例如: 從底部到頂部遍歷棧的迭代器:

// Iterate from bottom to top.        
public IEnumerable<T> BottomToTop
    {
        get
            {
                for (int i = 0; i < top; i++)
                    {
                        yield return values[i];
                    }
            }
    }

從頂部到底部部遍歷棧的另外一個迭代器:

// Iterate from top to bottom.
public IEnumerable<T> TopToBottom
        {
            get
            {
                // Since we implement IEnumerable<T>
                // and the default iteration is top to bottom,
                // just return the object.
                return this;
            }
        }

外部呼叫的相關程式碼如下:

// Prints: 9 8 7 6 5 4 3 2 1 0
// Foreach legal since s.TopToBottom returns IEnumerable<int>
foreach (int n in s.TopToBottom)
{
    System.Console.Write("{0} ", n);
}
System.Console.WriteLine();

// Prints: 0 1 2 3 4 5 6 7 8 9
// Foreach legal since s.BottomToTop returns IEnumerable<int>
foreach (int n in s.BottomToTop)
{
    System.Console.Write("{0} ", n);
}

支援部分迭代行為的迭代器:

// 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

參考來自: