This article mainly records my experience in learning the principle of foreach traversal in C#.
Traversing elements in a collection is an operation that is often involved in all encodings, so most programming languages write this process into syntax, such as foreach in C#. You will often see the following traversal code:
var lstStr = new List<string> { "a", "b" }; foreach (var str in lstStr) { (str); }
The actual execution process of this code:
var lstStr = new List<string> {"a", "b"}; IEnumerator<string> enumeratorLst = (); while (()) { (); }
You will find that there are GetEnumerator() methods and IEnumerator<string> types, which involves the concepts of enumerable types and enumerators.
For easy understanding, the following are non-generic examples:
// Summary:// Exposes an enumerator that supports simple iteration on non-generic collections. public interface IEnumerable { // Summary: // Returns an enumerator that loops through the collection. // // Return result: // Objects that can be used to iterate over the collection. IEnumerator GetEnumerator(); }
The class that implements this interface is called an enumerable type, and is a flag that can be traversed with foreach.
The return value of the method GetEnumerator() is an enumerator, which can be understood as a cursor.
// Summary:// Supports simple iteration of non-generic collections. public interface IEnumerator { // Summary: // Get the current element in the collection. // // Return result: // The current element in the collection. // // Exception: // : // Enumerations are positioned before or after the first element of the collection. object Current { get; } // Summary: // Propel the enumeration to the next element of the collection. // // Return result: // true if the enumeration is successfully advanced to the next element; false if the enumeration passes the end of the set. // // Exception: // : // The collection is modified after the enumeration is created. bool MoveNext(); // // Summary: // Set the enumeration number to its initial position, which is before the first element in the collection. // // Exception: // : // The collection is modified after the enumeration is created. void Reset(); }
Here is an example of customizing an iterator (/en-us/library/):
using System; using ; // Simple business object. public class Person { public Person(string fName, string lName) { = fName; = lName; } public string firstName; public string lastName; } // Collection of Person objects. This class // implements IEnumerable so that it can be used // with ForEach syntax. public class People : IEnumerable { private Person[] _people; public People(Person[] pArray) { _people = new Person[]; for (int i = 0; i < ; i++) { _people[i] = pArray[i]; } } // Implementation for the GetEnumerator method. IEnumerator () { return (IEnumerator) GetEnumerator(); } public PeopleEnum GetEnumerator() { return new PeopleEnum(_people); } } // When you implement IEnumerable, you must also implement IEnumerator. public class PeopleEnum : IEnumerator { public Person[] _people; // Enumerators are positioned before the first element // until the first MoveNext() call. int position = -1; public PeopleEnum(Person[] list) { _people = list; } public bool MoveNext() { position++; return (position < _people.Length); } public void Reset() { position = -1; } object { get { return Current; } } public Person Current { get { try { return _people[position]; } catch (IndexOutOfRangeException) { throw new InvalidOperationException(); } } } } class App { static void Main() { Person[] peopleArray = new Person[3] { new Person("John", "Smith"), new Person("Jim", "Johnson"), new Person("Sue", "Rabon"), }; People peopleList = new People(peopleArray); foreach (Person p in peopleList) ( + " " + ); } } /* This code produces output similar to the following: * * John Smith * Jim Johnson * Sue Rabon * */
With the keyword yield, we can create an enumerator in this way:
using System; using ; // Simple business object. public class Person { public Person(string fName, string lName) { = fName; = lName; } public string firstName; public string lastName; } // Collection of Person objects. This class // implements IEnumerable so that it can be used // with ForEach syntax. public class People : IEnumerable { private Person[] _people; public People(Person[] pArray) { _people = new Person[]; for (int i = 0; i < ; i++) { _people[i] = pArray[i]; } } // Implementation for the GetEnumerator method. IEnumerator () { for (int i = 0; i < _people.Length; i++) { yield return _people[i]; } } } class App { static void Main() { Person[] peopleArray = new Person[3] { new Person("John", "Smith"), new Person("Jim", "Johnson"), new Person("Sue", "Rabon"), }; People peopleList = new People(peopleArray); foreach (Person p in peopleList) ( + " " + ); } }
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.