C#学习之用迭代器实现枚举器
上一篇文章為自定義類實現(xiàn)了foreach的功能,但實現(xiàn)過程中要實現(xiàn)IEnumerator接口(包括MoveNext、Reset函數(shù)和Current屬性)以便GetEnumerator函數(shù)能獲取枚舉數(shù),有點復(fù)雜,有點繁瑣。
已經(jīng)知道:主要一個類實現(xiàn)了GetEnumerator函數(shù)就能foreach,而實現(xiàn)IEnumerator接口只是實現(xiàn) GetEnumerator函數(shù)的其中一個辦法,也就說還有其他辦法實現(xiàn)GetEnumerator函數(shù)了?是的,C#2.0為我們提供了一種很簡單的方 法來實現(xiàn)GetEnumerator函數(shù),那就是使用迭代器!(還記得吧,C#里的迭代器和C++里的是不同的)
下面是來自MSDN的解說:
?
迭代器概述
-
迭代器是可以返回相同類型的值的有序序列的一段代碼。
-
迭代器可用作方法、運算符或?get?訪問器的代碼體。
-
迭代器代碼使用?yield return?語句依次返回每個元素。yield break?將終止迭代。有關(guān)更多信息,請參見?yield。
-
可以在類中實現(xiàn)多個迭代器。每個迭代器都必須像任何類成員一樣有唯一的名稱,并且可以在?foreach?語句中被客戶端代碼調(diào)用,如下所示:foreach(int x in SampleClass.Iterator2){}
-
迭代器的返回類型必須為?IEnumerable、IEnumerator、IEnumerable<T> 或?IEnumerator<T>。
yield?關(guān)鍵字用于指定返回的值。到達(dá)?yield return?語句時,會保存當(dāng)前位置。下次調(diào)用迭代器時將從此位置重新開始執(zhí)行。
?
第一部分:使用默認(rèn)迭代器實現(xiàn)獲取枚舉數(shù)
1、定義Person類
View Code 1 public class Person2 {
3 public string Name;
4 public int Age;
5
6 public Person(string name, int age)
7 {
8 Name = name;
9 Age = age;
10 }
11
12 public override string ToString()
13 {
14 return "Name: " + Name + "\tAge: " + Age;
15 }
16 }
?
2、定義PeopleEnum1類,里面實現(xiàn)了GetEnumerator函數(shù)(也就是迭代器了,這是默認(rèn)的迭代器),但實現(xiàn)的過程相對于上一篇文 章里介紹的實現(xiàn)過程要簡單很多,這就是yield的功效。yield的實現(xiàn)原理這里就不詳說了,可以概括為:GetEnumerator函數(shù)里的迭代塊把 IEnumerator接口的MoveNext、Reset方法和Current屬性封裝了,但本質(zhì)沒變,只是我們使用起來更方便了。
1 public class PeopleEnum12 {
3 private Person[] _perple;
4
5 //構(gòu)造函數(shù)
6 public PeopleEnum1(Person[] list)
7 {
8 _perple = new Person[list.Length];
9 for (int i = 0; i < list.Length; i++)
10 {
11 _perple[i] = list[i];
12 }
13 }
14
15 public IEnumerator GetEnumerator()
16 {
17 for (int i = 0; i < _perple.Length; i++)
18 {
19 yield return _perple[i];
20 }
21 }
22
23 }
?
3、主函數(shù)代碼
View Code 1 class Program2 {
3 static void Main(string[] args)
4 {
5 Person[] persons = new Person[]
6 {
7 new Person("aaa", 20),
8 new Person("bbb", 21),
9 new Person("ccc", 22)
10 };
11
12 PeopleEnum1 peopleEnum = new PeopleEnum1(persons);
13
14 foreach (var item in peopleEnum)
15 {
16 System.Console.WriteLine(item);
17
18 }
19
20 System.Console.ReadKey();
21 }
22 }
運行,成功,嘿嘿
?
第二部分:自定義迭代器
?第一部分用默認(rèn)迭代器GetEnumerator 實現(xiàn)了類的foreach,我們也可以定義自己的迭代器來獲取自己想要的枚舉數(shù)。比較說,我想列舉出類中未成年人的信息,默認(rèn)的迭代器無能為力,該怎么實現(xiàn)自定義的迭代器呢?
1、為PeopleEnum1類添加一個迭代器 GetChildren ,在這里,這個迭代器是一個屬性,也可以定義為函數(shù)。對于類中的元素,只有Age 小于18的元素才 yield return ,其他的不要。
View Code?
?2、主函數(shù)代碼
View Code?
輸出結(jié)果:
可以看到,自定義的迭代器 GetChildren 成功foreach了。
?
注意:默認(rèn)迭代器 GetEnumerator 的返回類型是 IEnumerator ,并且在使用foreach時 in 后面直接是類名。而自定義迭代器 GetChildren 的返回類型是 IEnumerable,并且在使用foreach時 in 后面是 PeopleEnum.GetChildren(類名.迭代器名)。好像,好像是規(guī)定這樣子的,原理是什么還不清楚。
?引用自 :http://www.cnblogs.com/zouzf/archive/2012/02/22/2362954.html
轉(zhuǎn)載于:https://www.cnblogs.com/zhangchenliang/archive/2012/08/19/2646781.html
總結(jié)
以上是生活随笔為你收集整理的C#学习之用迭代器实现枚举器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AVL树学习笔记
- 下一篇: Install marvel and h