首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 迭代器模式實作指南:從 IEnumerable 到 yield return(一)

     編輯:關於C語言

前言

當你建立一個類別表現得像集合時,支援 foreach 迴圈遍歷會大幅提升使用體驗。C# 1.1 需手動實作 IEnumerable/IEnumerator 介面,C# 2.0 引入 yield return 大幅簡化實作。本文將從傳統模式開始,逐步演進到現代寫法。

一、範例場景:簡易 ListBox 類別

內部使用固定大小陣列儲存字串,提供 Add 與 GetNumEntries 方法:

public class ListBox
{
    private string[] strings = new string[8];
    private int count = 0;

    public ListBox(params string[] initialStrings)
    {
        foreach (string s in initialStrings)
        {
            strings[count++] = s;
        }
    }

    public void Add(string theString)
    {
        strings[count++] = theString;
    }

    public int GetNumEntries() => count;
}

二、C# 1.1 傳統實作:IEnumerable + IEnumerator

1. 實作 IEnumerable.GetEnumerator()


public IEnumerator GetEnumerator()
{
    return new ListBoxEnumerator(this);
}

2. 建立巢狀 IEnumerator 實作類別


private class ListBoxEnumerator : IEnumerator
{
    private ListBox listBox;
    private int index = -1;

    public ListBoxEnumerator(ListBox lb)
    {
        listBox = lb;
    }

    public object Current => listBox.strings[index];

    public bool MoveNext()
    {
        if (index < listBox.count - 1)
        {
            index++;
            return true;
        }
        return false;
    }

    public void Reset() => index = -1;
}

3. 使用示範


ListBox lb = new ListBox("Hello", "World");
lb.Add("Who");
lb.Add("Is");
lb.Add("John");
lb.Add("Galt");

foreach (string s in lb)
{
    Console.WriteLine("Value: {0}", s);
}

// 輸出:
// Hello
// World
// Who
// Is
// John
// Galt

三、關鍵介面關係圖解

介面角色核心成員
IEnumerable可列舉物件GetEnumerator() : IEnumerator
IEnumerator列舉器/游標Current, MoveNext(), Reset()

注意:IEnumerable 與 IEnumerator 是不同介面,前者代表「可被列舉的容器」,後者代表「列舉過程中的游標」。

四、設計模式:巢狀類別封裝

最佳實務是在 IEnumerable 類別內部定義 private class Enumerator : IEnumerator:

  • 封裝內部結構,外部不可直接存取
  • 列舉器透過建構函式取得外部類別參考
  • 符合單一職責原則

五、下篇預告

下一篇將介紹 C# 2.0 的革命性簡化:

  • yield return 自動產生列舉器
  • 狀態機編譯器魔法原理
  • 泛型 IEnumerable<T> 與 IEnumerator<T>
  • 效能比較與最佳實務
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved