迭代器

迭代器也是C# 2.0的产物。

    1.1 迭代器的简介

         迭代器记录了集合中的某个位置,它使程序只能向前移动。C# 1.0中使用foreach语句来实现访问迭代器的内置支持,foreach使遍历集合变得简单,它比for语句更方便,也更容易理解。foreach被编译器编译后,会调用GetEnumerator来返回一个迭代器,也就是一个集合中的初始位置。

    1.2 C# 1.0中如何实现迭代器

         一个类型想要使用foreach关键字进行遍历,它必须实现IEnumerable或IEnumerable<T>接口。IEnumerable接口中定义了一个GetEnumerator方法用来返回迭代器,类型如果实现了IEnumerable接口,则也必须实现GetEnumerator方法。

        

 1 namespace 迭代器
 2 {
 3     class Program
 4     {
 5         static void Main(string[] args)
 6         {
 7             Friends friendcollection=new Friends();
 8             foreach (Friend friend in friendcollection)
 9             {
10                 Console.WriteLine(friend.Name);
11             }
12             Console.ReadKey();
13         }
14     }
15 
16     public class Friend
17     {
18         private string name;
19         public string Name
20         {
21             get { return name; }
22             set { name = value; }
23         }
24 
25         public Friend(string name)
26         {
27             this.name = name;
28         }
29     }
30 
31     public class Friends : IEnumerable
32     {
33         private Friend[] friendarray;
34 
35         public Friends()
36         {
37             friendarray=new Friend[]
38             {
39                 new Friend("张三"),
40                 new Friend("李四"),
41                 new Friend("王五"),   
42             };
43         }
44 
45         //索引器
46         public Friend this[int index] => friendarray[index];
47 
48         public int Count => friendarray.Length;
49         
50         //实现IEnumerable<T>接口的方法
51         public IEnumerator GetEnumerator()
52         {
53             return new FriendIterator(this);
54         }
55     }
56 
57     public class FriendIterator : IEnumerator
58     {
59         private readonly Friends friends;
60         private int index;
61         private Friend current;
62         internal FriendIterator(Friends friendcollection)
63         {
64             this.friends = friendcollection;
65             index = 0;
66         }
67         
68         public bool MoveNext()
69         {
70             if (index + 1 > friends.Count)
71             {
72                 return false;
73             }
74             else
75             {
76                 this.current = friends[index];
77                 index++;
78                 return true;
79             }
80         }
81 
82         public void Reset()
83         {
84             index = 0;
85         }
86         //实现IEnumerator接口中的方法
87         public object Current => this.current;
88 
89     }
90 }

    从以上的代码可以看出,在C# 1.0中,要使用某个类型可以迭代是需要写大量代码的。

    1.3 C# 2.0简化了迭代器的实现

          不说这么多,直接上代码:

          

 1 namespace 迭代器
 2 {
 3     class Program
 4     {
 5         static void Main(string[] args)
 6         {
 7             Friends friendcollection=new Friends();
 8             foreach (Friend friend in friendcollection)
 9             {
10                 Console.WriteLine(friend.Name);
11             }
12             Console.ReadKey();
13         }
14     }
15 
16     public class Friend
17     {
18         private string name;
19         public string Name
20         {
21             get { return name; }
22             set { name = value; }
23         }
24 
25         public Friend(string name)
26         {
27             this.name = name;
28         }
29     }
30 
31     public class Friends : IEnumerable
32     {
33         private Friend[] friendarray;
34 
35         public Friends()
36         {
37             friendarray=new Friend[]
38             {
39                 new Friend("张三"),
40                 new Friend("李四"),
41                 new Friend("王五"),   
42             };
43         }
44 
45         //索引器
46         public Friend this[int index] => friendarray[index];
47 
48         public int Count => friendarray.Length;
49         
50         //实现IEnumerable<T>接口的方法
51         public IEnumerator GetEnumerator()
52         {
53             for (int index = 0; index < friendarray.Length; index++)
54             {
55                 //在C# 2.0中,只需要使用下面的语句就可以实现一个迭代器
56                 yield return friendarray[index];
57             }
58         }
59     }
60 }

    这段代码只用了一个yield return就完成了迭代器的实现,它作用就是在告诉编译器,GetEnumerator方法不是一个普通的方法,而是实现迭代器的方法。当编译器看到yield return 语句时,会在中间代码中为我们生成了一个IEnumerator接口的对象。可以使用反射工具Reflector看一下。

     

由上图可以看出,yield return语句其实是C#中提供的另一个语法糖(语法糖可以理解为C#提供的一种方便形式),它简化了我们的迭代器源代码,把具体而复杂的实现过程留给了编译器去完成。

原文地址:https://www.cnblogs.com/Helius/p/5755097.html