11. C # iterator (Chapter 6 6.1 ),
Today, let's talk about the iterator in C #. First, we will introduce some concepts about iteration, And I will introduce the code for your discussion.
The iterator mode is an example of the behavior mode, and the behavior mode is a design mode that simplifies communication between objects. In. NET uses the IEnumerator and IEnumerable interfaces and Their wildcard equivalents to encapsulate. If a type implements the IEnumerable interface, it indicates that it can be iterated, call the GetEnumerator method to return the implementation of IEnumerator, which is the iterator itself.
C #1 uses the foreach statement to implement built-in support for the access iterator. The foreach statement is compiled into the GetEnumerator, MoveNext method, and Current attribute. In C #, The iterator can only be accessed backward, while in C ++, The iterator can be accessed before and after.
Background. Suppose there is a queue for students, and each Student returns its name in turn. Student class is as follows:
1 class Student 2 { 3 public string Name { get; set; } 4 5 public Student(string name) 6 { 7 Name = name; 8 } 9 10 public void SayName()11 {12 Console.WriteLine(Name);13 }14 }
There is a generic Queue class that implements IEnumerable, as shown below
1 class Queue <T>: IEnumerable <T> where T: class 2 {3 public List <T> objects = new List <T> (); 4 5 public Queue (List <T> list) 6 {7 objects = list; 8} 9 10 // implement the GetEnumerator method from IEnumerable 11/* 12 personally think this method will be called only once in iteration, otherwise, a new QueueIterator <T> object will be returned each time, and the location record will be reset to-113 */14 public IEnumerator <T> GetEnumerator () 15 {16 return new QueueIterator <T> (this); 17} 18 19 IEnumerator IEnumerable. getEnumerator () 20 {21 throw new NotImplementedException (); 22} 23}
Use the GetEnumerator method to return an iterator. The iterator must implement the IEnumerator interface, as shown below:
1 class QueueIterator <T>: IEnumerator <T> where T: class 2 {3 private ConsoleDemo. chapter6.Queue <T> q = null; 4 5 int startPoint =-1; // used to save the cursor position 6 7 public QueueIterator (ConsoleDemo. chapter6.Queue <T> q) 8 {9 this. q = q; 10} 11 12 // return the T-type instance in the proper position, in this example, the automatic attribute 13 public T Current14 {15 get16 {17 if (startPoint =-1 | startPoint = q. objects. count) 18 {19 throw new InvalidOperationException (); 20} 21 Int index = startPoint + q. objects. count; 22 index = index % q. objects. count; 23 return q. objects [index]; 24} 25} 26 27 object IEnumerator. current28 {29 get30 {31 if (startPoint =-1 | startPoint = q. objects. count) 32 {33 throw new InvalidOperationException (); 34} 35 int index = startPoint + q. objects. count; 36 index = index % q. objects. count; 37 return q. objects [index]; 38} 39} 40 41 public void Disp Ose () 42 {43 44} 45 46 public bool MoveNext () 47 {48 if (startPoint! = Q. objects. count) 49 {50 startPoint ++; 51} 52 return startPoint <q. objects. count; 53} 54 // when the iteration ends, this method is called, And the next iteration starts from the first position 55 public void Reset () 56 {57 startPoint =-1; 58} 59}
Implement the Current attribute, Dispose method (if necessary), MoveNext method, and Reset method in IEnumerator respectively. Use the yield statement in C #2 to simplify the iterator.
Please make an axe.