定義參考 wiki: Iterator patternhtml
迭代器模式就是分離了集合對象的遍歷行爲,抽象出一個迭代器類來負責,這樣既能夠作到不暴露集合的內部結構,又可以讓外部代碼透明地訪問集合內部的數據。 ------- 節選自 《大話設計模式》P207 設計模式
咱們能夠將迭代器模式抽離出幾個重要組成部分:app
1. 迭代器抽象類ide
2. 彙集抽象類oop
3. 具體迭代器類學習
4. 具體彙集類ui
1 public interface IEnumerator 2 { 3 bool MoveNext(); 4 5 Object Current { 6 get; 7 } 8 9 void Reset(); 10 }
reference: .NET IEnumeratorthis
1 public interface IEnumerable 2 { 3 IEnumerator GetEnumerator(); 4 }
reference: .NET IEnumerablespa
經過查看.NET代碼能夠知道,在List、Dictionary類中都聲明瞭具體的迭代器struct Enumerator,List中Enumerator代碼以下:設計
1 [Serializable] 2 public struct Enumerator : IEnumerator<T>, 3 System.Collections.IEnumerator 4 { 5 private List<T> list; 6 private int index; 7 private int version; 8 private T current; 9 10 internal Enumerator(List<T> list) { 11 this.list = list; 12 index = 0; 13 version = list._version; 14 current = default(T); 15 } 16 17 public void Dispose() { 18 } 19 20 public bool MoveNext() { 21 22 List<T> localList = list; 23 24 if (version == localList._version && ((uint)index < (uint)localList._size)) 25 { 26 current = localList._items[index]; 27 index++; 28 return true; 29 } 30 return MoveNextRare(); 31 } 32 33 private bool MoveNextRare() 34 { 35 if (version != list._version) { 36 ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion); 37 } 38 39 index = list._size + 1; 40 current = default(T); 41 return false; 42 } 43 44 public T Current { 45 get { 46 return current; 47 } 48 } 49 50 Object System.Collections.IEnumerator.Current { 51 get { 52 if( index == 0 || index == list._size + 1) { 53 ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen); 54 } 55 return Current; 56 } 57 } 58 59 void System.Collections.IEnumerator.Reset() { 60 if (version != list._version) { 61 ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion); 62 } 63 64 index = 0; 65 current = default(T); 66 } 67 }
reference: .NET List Enumerator
一樣以List爲例,reference: .NET List
foreach(int i in obj) {...}通過編譯器轉換將會變成以下:
var tmp = obj.GetEnumerator(); int i; while (tmp.MoveNext()) { i = tmp.Current; {...} // your code }
因此能夠知道,只要咱們實現了迭代器類和彙集類,那麼就能夠經過foreach來進行遍歷了。
1. How do foreach loops work in C#?
3. 詳解C# 迭代器