How can For each...
Answer: To keep it short the compiler doesn't do much. It just translates the foreach code into a while under the hood. Here's an example:
List<int> list = new List<int>;
........
foreach(int item in list)
{
//Do stuff
}
Becomes:
Enumerator<int> enum = ((IEnumerable<int>)list).GetEnumerator();
enum.Reset();
while(enum.MoveNext())
{
int item = enum.Current;
//Do stuff
}
or something very close to that. The acual code compiled most likely has a try / finally block around the while to dispose the enumerator
IEnumerable is the base interface for all non-generic collections that can be enumerated. For the generic version of this interface see System.Collections.Generic.IEnumerable<T>. IEnumerable contains a single method, GetEnumerator, which returns an IEnumerator. IEnumerator provides the ability to iterate through the collection by exposing a Current property and MoveNext and Reset methods.
It is a best practice to implement IEnumerable and IEnumerator on your collection classes to enable the foreach (For Each in Visual Basic) syntax, however implementing IEnumerable is not required. If your collection does not implement IEnumerable, you must still follow the iterator pattern to support this syntax by providing a GetEnumerator method that returns an interface, class or struct. When using Visual Basic, you must provide an IEnumerator implementation, which is returned by GetEnumerator. When developing with C# you must provide a class that contains a Current property, and MoveNext and Reset methods as described by IEnumerator, but the class does not have to implement IEnumerator.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections; namespace CSharpExam { public class TestInumerable { public static void Run() { Person[] peopleArray = new Person[3] { new Person("Steven", "Xia"), new Person("Jim", "Johnson"), new Person("Sue", "Rabon"), }; People peopleList = new People(peopleArray); foreach (Person p in peopleList) Console.WriteLine(p.firstName + " " + p.lastName); } } public class Person { public Person(string fName, string lName) { this.firstName = fName; this.lastName = lName; } public string firstName; public string lastName; } public class People //: IEnumerable { private Person[] _people; public People(Person[] pArray) { _people = new Person[pArray.Length]; for (int i = 0; i < pArray.Length; i++) { _people[i] = pArray[i]; } } #region IEnumerable 成员 public PeopleEnum GetEnumerator() { return new PeopleEnum(_people); } #endregion } 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; } public object Current { get { try { return _people[position]; } catch (IndexOutOfRangeException) { throw new InvalidOperationException(); } } } } }