Use the yield keyword to implement foreach traversal for a custom set.
Generally, when we create a custom set, we can only implement the IEnumerable interface (which may also implement the IEnumerator Interface) to support foreach traversal)
However, we can also use the iterator Method built with the yield keyword to implement foreach traversal, And the custom set does not need to implement the IEnumerable interface.
Note: although you do not need to implement the IEnumerable interface, the method of the iterator must be named GetEnumerator (), and the returned value must also be of the IEnumerator type.
The instance code and simple instructions are as follows:
1 class Person 2 {3 public string Name; 4 public void SayHi () 5 {6 Console. writeLine ("Hello: {0}", this. name); 7} 8} 9 // very simple custom set (-simple to add, delete, index, and other functions are not implemented) this class does not implement the IEnumerable interface 10 class PersonList11 {12 Person [] pers = new Person [4]; 13 public PersonList () 14 {15 pers [0] = new Person () {Name = "1"}; 16 pers [1] = new Person () {Name = "2"}; 17 pers [2] = new Person () {Name = "3"}; 18 pers [3] = new Person () {Name = "4 "}; 19 20} 21 // simple iterator Method 22 public IEnumerator GetEnumerator () 23 {24 25 foreach (Person item in pers) 26 {27 // yield return is used to return an element of the set and move it to 28 yield return item on the next element; 29} 30 31} 32} 33 class Program34 {35 static void Main (string [] args) 36 {37 PersonList list = new PersonList (); 38 foreach (Person item in list) 39 {40 item. sayHi (); 41} 42 Console. readLine (); 43} 44}
Interface to be inherited for foreach Traversal
When using FOREACH to traverse a set, it is required that the object to be traversed must implement the IENUMABLE interface, and the unique member method GETENUMATOR of this interface returns the instance object that implements the IENUMATOR interface.
Check IENUMATOR and find three members: CURRENT, MOVENEXT, and RESET. CURRENT returns the CURRENT member object. MOVENEXT moves the pointer down to a position, if an instance Member exists, true is returned; otherwise, false is returned, which is the condition for FOREACH to determine the end of the loop; RESET is used to RESET the loop pointer.
Through the above analysis, it is assumed that the IENUMATOR interface is implemented together when the class implementing the IENUMABLE interface is defined, and no problem is found. When you need to perform FOREACH for the custom set twice in a day, you will find that the first time OK, the second time there is a problem, depressed. Debugging has not solved the problem for a long time.
After testing and tracking in multiple aspects, it is found that FOREACH does not call the RESET method of RESET. Therefore, when the second FOREACH is executed, the member pointer has reached the end, And MOVENEXT always returns false, previously, it was assumed that when FOREACH was called, either the RESET was executed or the RESET was last executed, but the result was not.
Decompile the Code defined by MS for the Collection class and find that when the class implements the IENUMABLE method GETENUMATOR, It is a brand new class instance that implements the IENUMATOR interface, therefore, there will be no abnormal data during consecutive FOREACH hours.
Why does MS use this solution to implement IENUMATOR? It's also silly to think about it. If an instance set is FOREACH at the same time in multiple threads, isn't the pointer messy? This implementation scheme is MS to ensure the security of the Collection class instances in the multi-threaded environment.
Use foreach loop to traverse array a at a time
Int [,] a = new int [2, 2, 2] {1, 2}, {3, 4}, {5, 6 }, {7, 8 }}; // defines a two-row, two-column, two-depth, three-dimensional array.
Foreach (int I in)
{
Console. WriteLine (I );
}
The execution results of these two types of code are the same. Each line has one element, eight rows in total, and the elements are 1 2 3 4 5 6 7 8 respectively.
Jstl foreach traverses the same set twice, for example, list set
You should not use the value in the first foreach var as a list or a name, because in this case, the second EL expression $ {list} does not know which one it is.