static void Main(string[] args)
{
List listArray = new List();
listArray.Add(100);
foreach (int item in listArr
From the C# 3.0 language spec (Sec. 8.8.4):
The compile-time processing of a foreach statement first determines the collection type, enumerator type and element type of the expression. This determination proceeds as follows:
Otherwise, determine whether the type X has an appropriate GetEnumerator method:
a. Perform member lookup on the type X with identifier GetEnumerator and no type arguments. If the member lookup does not produce a match, or it produces an ambiguity, or produces a match that is not a method group, check for an enumerable interface as described below. It is recommended that a warning be issued if member lookup produces anything except a method group or no match.
b. Perform overload resolution using the resulting method group and an empty argument list. If overload resolution results in no applicable methods, results in an ambiguity, or results in a single best method but that method is either static or not public, check for an enumerable interface as described below. It is recommended that a warning be issued if overload resolution produces anything except an unambiguous public instance method or no applicable methods.
c. If the return type E of the GetEnumerator method is not a class, struct or interface type, an error is produced and no further steps are taken.
d. Member lookup is performed on E with the identifier Current and no type arguments. If the member lookup produces no match, the result is an error, or the result is anything except a public instance property that permits reading, an error is produced and no further steps are taken.
e. Member lookup is performed on E with the identifier MoveNext and no type arguments. If the member lookup produces no match, the result is an error, or the result is anything except a method group, an error is produced and no further steps are taken.
f. Overload resolution is performed on the method group with an empty argument list. If overload resolution results in no applicable methods, results in an ambiguity, or results in a single best method but that method is either static or not public, or its return type is not bool, an error is produced and no further steps are taken.
g. The collection type is X, the enumerator type is E, and the element type is the type of the Current property.
In summary, the compiler acts as if the foreach were the following code, making polymorphic calls and looking at the defined enumerable interface definition (if any) to determine the proper types and methods:
var iterator = listArray.GetEnumerator();
while(iterator.MoveNext())
{
var item = iterator.Current;
Console.WriteLine(item);
}