枚舉數
枚舉數是逐一查看其關聯集合的對象。它可被視作指向集合中任何元素的可移動的指標。 一個枚舉數只能與一個集合關聯,但一個集合可以具有多個枚舉數。C#的foreach 語句使用枚舉數並隱藏操作該枚舉數的複雜性。枚舉數可用於讀取集合中的資料,但不能用於修改基礎集合。
集合要支援foreach則需要實現System.Collections.IEnumerable介面[公開枚舉數,該枚舉數支援在非泛型集合上進行簡單迭代, 也可以不實現該介面,該介面定義了一個方法GetEnumerator(),返回一個支援IEnumerator介面的對象,IEnumerator的成員如下:
| 名稱 |
說明 |
| bool MoveNex t方法 |
將枚舉數推進到集合的下一個元素 |
| void Rese t方法 |
將枚舉數設定為其初始位置,該位置位於集合中第一個元素之前 |
| object Current 屬性 |
擷取集合中的當前元素 |
寫一個:
1 2 public class MyCollections : IEnumerable 3 { 4 private string[] items; 5 MyCollections(string[] items) 6 { 7 this.items = items; 8 } 9 public IEnumerator GetEnumerator()10 {11 return new MyEnumerator(this);12 }13 public class MyEnumerator : IEnumerator14 {15 private int position = -1;16 private MyCollections mc;17 public MyEnumerator(MyCollections mc)18 {19 this.mc = mc;20 }21 public bool MoveNext()22 {23 if (position < this.mc.items.Length - 1)24 {25 position++;26 return true;27 }28 else29 {30 return false;31 }32 }33 public void Reset()34 {35 position = -1;36 }37 object IEnumerator.Current38 {39 get40 {41 return this.mc.items[position];42 }43 }44 }45 static void Main()46 {47 MyCollections f = new MyCollections(48 new string[] { "亂舞春秋", "男", "22" });49 foreach (string item in f)50 {51 Console.WriteLine(item);52 }53 }54 }迭代器
C#2.0以前,要使自己的集合支援foreach遍曆,需要寫上面一大堆代碼[實現兩個介面,也可不實現, 但是必須給提供這兩個介面中的同名方法],C#2.0引入了yield return[返回每個元素]和yield break[終止迭代]兩個組合而成的內容關鍵字。 改寫上述代碼:
//MyEnumerable方法全部刪掉public IEnumerator GetEnumerator(){ for (int i = 0; i < items.Length; i++) { yield return items[i]; }}
就是這麼簡單!只需實現一個介面IEnumerable就可以了[或者說有public IEnumerator GetEnumerator()此方法就可];
像是匿名方法一樣,編譯器幫我們做了很多[這裡編譯器幫我們產生了"實現IEnumerator介面的一個類",通過查看IL代碼得知]。