在軟體開發中,集合類別(陣列、列表、樹、圖)內部結構各異,但客戶端常需以統一方式順序存取元素。若暴露集合內部結構(如索引、節點指標),會導致客戶端與集合緊耦合,且難以支援多種遍歷策略(正向、反向、跳躍、過濾)。迭代器模式提供標準解決方案:將遍歷邏輯從集合中分離,封裝於獨立的迭代器物件中,提供統一介面存取元素,且不暴露集合內部表示。本文透過可自定義步長的訊息集合遍歷完整展示迭代器模式實作。
ICollection,定義 CreateIterator() 工廠方法。Collection,實作 CreateIterator() 回傳專屬迭代器,內部以 List<MessageModel> 儲存資料,提供索引器與 Count 屬性供迭代器存取。IIterator,定義遍歷協定:First()、Next()、CurrentMessageModel、IsDone、Step(步長)。Iterator,持有聚合參考與游標 _current,實作具體遍歷邏輯(含步長跳躍)。
public interface IIterator
{
MessageModel First(); // 移至第一個並回傳
MessageModel Next(); // 移至下一個並回傳
MessageModel CurrentMessageModel { get; } // 當前元素
bool IsDone { get; } // 是否遍歷結束
int Step { get; set; } // 步長(擴展點)
}
擴展 Step 屬性支援「跳躍遍歷」,展示迭代器封裝遍歷策略的靈活性。
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)封裝在迭代器中,支援同一集合同時存在多個獨立迭代器。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() 為工廠方法,讓聚合決定建立哪種迭代器(可根據條件回傳不同實作,如反向迭代器、過濾迭代器)。
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 Framework 內建標準化迭代器模式:
IEnumerable<T> 對應 Aggregate,提供 GetEnumerator()。IEnumerator<T> 對應 Iterator,提供 MoveNext()、Current、Reset()。foreach 編譯器語法糖自動處理迭代器生命週期。實務建議:自訂集合實作 IEnumerable<T>,即可獲得 foreach、LINQ、序列化等生態支援。
yield return 編譯器自動生成狀態機實作 IEnumerable,極大簡化迭代器撰寫。Where、Select、Skip)本質上是裝飾迭代器,組合形成查詢管道。IAsyncEnumerable<T> 支援 await foreach,適用於資料庫串流、網路分頁。foreach 中修改集合會拋出 InvalidOperationException。解決:先 ToList() 複製、或使用倒序迴圈、或收集待刪除項目稍後處理。yield return 延遲執行,避免一次載入所有資料到記憶體。迭代器模式將「如何遍歷」從「儲存什麼」中分離,提供統一、可擴展的元素存取介面。本範例以可自定義步長的訊息集合為例,完整展示了抽象聚合、具體聚合、抽象迭代器、具體迭代器四角色協作,並驗證了跳躍遍歷策略的封裝優勢。在 .NET 生態中,IEnumerable<T>/IEnumerator<T> 與 yield return 已將此模式內建於語言層級,掌握其核心機制,能讓你在設計自訂集合、資料管道、非同步串流時,充分發揮標準化遍歷介面的威力,編寫出更優雅、可組合、效能更好的程式碼。