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

C# 迭代器模式完全指南:統一遍歷介面與自定義迭代邏輯

     編輯:關於C#

前言

在軟體開發中,集合類別(陣列、列表、樹、圖)內部結構各異,但客戶端常需以統一方式順序存取元素。若暴露集合內部結構(如索引、節點指標),會導致客戶端與集合緊耦合,且難以支援多種遍歷策略(正向、反向、跳躍、過濾)。迭代器模式提供標準解決方案:將遍歷邏輯從集合中分離,封裝於獨立的迭代器物件中,提供統一介面存取元素,且不暴露集合內部表示。本文透過可自定義步長的訊息集合遍歷完整展示迭代器模式實作。

模式結構與四大角色

  • Aggregate(抽象聚合):ICollection,定義 CreateIterator() 工廠方法。
  • ConcreteAggregate(具體聚合):Collection,實作 CreateIterator() 回傳專屬迭代器,內部以 List<MessageModel> 儲存資料,提供索引器與 Count 屬性供迭代器存取。
  • Iterator(抽象迭代器):IIterator,定義遍歷協定:First()、Next()、CurrentMessageModel、IsDone、Step(步長)。
  • ConcreteIterator(具體迭代器):Iterator,持有聚合參考與游標 _current,實作具體遍歷邏輯(含步長跳躍)。
迭代器模式類別圖

核心程式碼機制深度解析

1. 抽象迭代器:定義遍歷協定

public interface IIterator
{
    MessageModel First();           // 移至第一個並回傳
    MessageModel Next();            // 移至下一個並回傳
    MessageModel CurrentMessageModel { get; } // 當前元素
    bool IsDone { get; }            // 是否遍歷結束
    int Step { get; set; }          // 步長(擴展點)
}

擴展 Step 屬性支援「跳躍遍歷」,展示迭代器封裝遍歷策略的靈活性。

2. 具體迭代器:游標管理與邏輯封裝

public class Iterator : IIterator
{
    private Collection _collection;
    private int _current = 0;
    private int _step = 1;

    public Iterator(Collection collection) { this._collection = collection; }

    public MessageModel First()
    {
        _current = 0;
        return _collection[_current];
    }

    public MessageModel Next()
    {
        _current += _step;
        if (!IsDone)
            return _collection[_current];
        return null;
    }

    public MessageModel CurrentMessageModel 
        => _collection[_current];

    public bool IsDone 
        => _current >= _collection.Count;

    public int Step { get => _step; set => _step = value; }
}

關鍵點:

  • 迭代器持有聚合參考,透過索引器存取元素,不需知道聚合內部用 List、陣列或鏈表。
  • Next() 結合 Step 實現跳躍邏輯,IsDone 防止越界。
  • 狀態(_current、_step)封裝在迭代器中,支援同一集合同時存在多個獨立迭代器。

3. 聚合介面與實作:工廠方法建立迭代器

public interface ICollection
{
    IIterator CreateIterator();
}

public class Collection : ICollection
{
    private List<MessageModel> list = new List<MessageModel>();

    public IIterator CreateIterator() => new Iterator(this);

    public int Count => list.Count;

    public MessageModel this[int index]
    {
        get => list[index];
        set => list.Add(value); // 簡化:set 視為 Add
    }
}

CreateIterator() 為工廠方法,讓聚合決定建立哪種迭代器(可根據條件回傳不同實作,如反向迭代器、過濾迭代器)。

4. 客戶端:統一遍歷介面與自定義步長

I.Collection collection = new I.Collection();
for (int i = 1; i <= 9; i++)
    collection[i-1] = new I.MessageModel("第" + i + "條信息", DateTime.Now);

I.Iterator iterator = new I.Iterator(collection);
iterator.Step = 2; // 設定步長為 2:跳躍遍歷

for (I.MessageModel mm = iterator.First(); !iterator.IsDone; mm = iterator.Next())
{
    Response.Write(mm.Message + "<br />");
}

執行結果驗證

第1條信息
第3條信息
第5條信息
第7條信息
第9條信息

步長為 2 時,正確輸出索引 0, 2, 4, 6, 8 的元素,驗證迭代器封裝「跳躍遍歷」策略的能力。

進階應用與 .NET 生態整合

內建介面:IEnumerable<T> 與 IEnumerator<T>

.NET Framework 內建標準化迭代器模式:

  • IEnumerable<T> 對應 Aggregate,提供 GetEnumerator()。
  • IEnumerator<T> 對應 Iterator,提供 MoveNext()、Current、Reset()。
  • foreach 編譯器語法糖自動處理迭代器生命週期。

實務建議:自訂集合實作 IEnumerable<T>,即可獲得 foreach、LINQ、序列化等生態支援。

迭代器模式的現代變體

  • 生成器:C# yield return 編譯器自動生成狀態機實作 IEnumerable,極大簡化迭代器撰寫。
  • 管道/流式處理:LINQ 操作符(Where、Select、Skip)本質上是裝飾迭代器,組合形成查詢管道。
  • 非同步迭代器:C# 8.0 IAsyncEnumerable<T> 支援 await foreach,適用於資料庫串流、網路分頁。

常見陷阱與最佳實務

  • 修改集合時迭代:foreach 中修改集合會拋出 InvalidOperationException。解決:先 ToList() 複製、或使用倒序迴圈、或收集待刪除項目稍後處理。
  • 迭代器失效:自訂迭代器需在集合結構變更時重置或拋出異常。
  • 大量資料:使用 yield return 延遲執行,避免一次載入所有資料到記憶體。

優缺點總結

優點

  • 單一職責:遍歷邏輯從集合分離。
  • 開閉原則:新增遍歷策略(反向、過濾、跳躍)無需修改集合類別。
  • 支援同一集合多種並發遍歷(每個迭代器獨立狀態)。
  • 統一介面:客戶端以相同方式遍歷陣列、列表、樹、資料庫結果集。

缺點

  • 簡單集合(如陣列)使用迭代器可能過度設計。
  • 某些遍歷操作(如隨機存取、回溯)用迭代器介面不便。
  • 需額外類別增加系統複雜度。

總結

迭代器模式將「如何遍歷」從「儲存什麼」中分離,提供統一、可擴展的元素存取介面。本範例以可自定義步長的訊息集合為例,完整展示了抽象聚合、具體聚合、抽象迭代器、具體迭代器四角色協作,並驗證了跳躍遍歷策略的封裝優勢。在 .NET 生態中,IEnumerable<T>/IEnumerator<T> 與 yield return 已將此模式內建於語言層級,掌握其核心機制,能讓你在設計自訂集合、資料管道、非同步串流時,充分發揮標準化遍歷介面的威力,編寫出更優雅、可組合、效能更好的程式碼。


參考資源:DoFactory Iterator Pattern

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved