【迭代器模式在.NET中的應用】

 

迭代器模式

  定義參考 wiki: Iterator patternhtml

  迭代器模式就是分離了集合對象的遍歷行爲,抽象出一個迭代器類來負責,這樣既能夠作到不暴露集合的內部結構,又可以讓外部代碼透明地訪集合內部的數據。   ------- 節選自 《大話設計模式》P207 設計模式

  咱們能夠將迭代器模式抽離出幾個重要組成部分:app

  1. 迭代器抽象類ide

  2. 彙集抽象類oop

  3. 具體迭代器類學習

  4. 具體彙集類ui

 

1. 迭代器抽象類

 1 public interface IEnumerator
 2 {
 3         bool MoveNext();
 4     
 5         Object Current {
 6             get; 
 7         }
 8     
 9         void Reset();
10 }
View Code

reference: .NET IEnumeratorthis

 

2. 彙集抽象類

1 public interface IEnumerable
2 {
3         IEnumerator GetEnumerator();
4 }
View Code

reference: .NET IEnumerablespa

 

3. 具體迭代器類

經過查看.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 }
View Code

reference: .NET List Enumerator

 

4. 具體彙集類

一樣以List爲例,reference: .NET List

 

5. 利用 foreach 來遍歷對象

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#?

2. Foreach On IEnumerable

3. 詳解C# 迭代器

4. .Net學習難點討論系列11 - foreach與迭代器

相關文章
相關標籤/搜索