Iterator, generator
 
The iterator is also a product of C #2.0.
 
1.1 Introduction to The iterator
 
The iterator records a position in the set so that the program can only move forward. In C #1.0, the foreach statement is used to implement built-in support for the access iterator. foreach makes the traversal set easier and easier to understand than the for statement. After the foreach is compiled by the compiler, GetEnumerator is called to return an iterator, that is, the initial position in a set.
 
1.2 How to Implement the iterator in C #1.0
 
To use the foreach keyword for traversal, a type must implement the IEnumerable or IEnumerable <T> interface. The IEnumerable interface defines a GetEnumerator method to return the iterator. If the type implements the IEnumerable interface, the GetEnumerator method must also be implemented.
 
 
1 namespace iterator 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 Friend17 {18 private string name; 19 public string Name20 {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: IEnumerable32 {33 private Friend [] friendarray; 34 35 public Friends () 36 {37 friendarray = new Friend [] 38 {39 new Friend ("Zhang San"), 40 new Friend ("Li Si"), 41 new Friend ("Wang Wu "), 42}; 43} 44 45 // indexer 46 public Friend this [int index] => friendarray [index]; 47 48 public int Count => friendarray. length; 49 50 // method for implementing the IEnumerable <T> interface 51 public IEnumerator GetEnumerator () 52 {53 return new FriendIterator (this); 54} 55} 56 57 public class FriendIterator: IEnumerator58 {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 else75 {76 this. current = friends [index]; 77 index ++; 78 return true; 79} 80} 81 82 public void Reset () 83 {84 index = 0; 85} 86 // implement the method 87 public object Current in the IEnumerator interface => this. current; 88 89} 90} 
From the code above, we can see that in C #1.0, a large amount of code is required to use a certain type of iteration.
 
 
 
1.3 C #2.0 simplifies the implementation of the iterator
 
If you don't talk so much about it, go directly to the Code:
 
 
1 namespace iterator 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 Friend17 {18 private string name; 19 public string Name20 {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: IEnumerable32 {33 private Friend [] friendarray; 34 35 public Friends () 36 {37 friendarray = new Friend [] 38 {39 new Friend ("Zhang San"), 40 new Friend ("Li Si"), 41 new Friend ("Wang Wu "), 42}; 43} 44 45 // indexer 46 public Friend this [int index] => friendarray [index]; 47 48 public int Count => friendarray. length; 49 50 // method for implementing the IEnumerable <T> interface 51 public IEnumerator GetEnumerator () 52 {53 for (int index = 0; index <friendarray. length; index ++) 54 {55 // in C #2.0, you only need to use the following statement to implement an iterator 56 yield return friendarray [index]; 57} 58} 59} 60} 
This Code uses only one yield return to implement the iterator. It is used to tell the compiler that the GetEnumerator method is not a common method, but an iterator method. When the compiler sees the yield return statement, it will generate an IEnumerator interface object for us in the intermediate code. You can use the reflection tool Reflector.
 
 
It can be seen that the yield return Statement is actually another syntactic sugar provided by C # (syntactic sugar can be understood as a convenient form provided by C ), it simplifies the source code of our iterator and leaves the specific and complex implementation process to the compiler.