The foreach
statement enumerates the elements of a collection, executing an embedded statement for each element of the collection.
The type and identifier of a foreach
statement declare the iteration variable of the statement. The iteration variable corresponds to a read-only local variable with a scope that extends over the embedded statement. During execution of a foreach
statement, the iteration variable represents the collection element for which an iteration is currently being performed. A compile-time error occurs if the embedded statement attempts to assign to the iteration variable or pass the iteration variable as a ref
or out
parameter.
The type of the expression of a foreach
statement must be a collection type (as defined below), and an explicit conversion (§6.2) must exist from the element type of the collection to the type of the iteration variable.
A type C
is said to be a collection type if all of the following are true:
C
contains a public
instance method with the signature GetEnumerator()
that returns a struct-type, class-type, or interface-type, in the following called E
.E
contains a public
instance method with the signature MoveNext()
and the return type bool
.E
contains a public
instance property named Current
that permits reading. The type of this property is said to be the element type of the collection type.The System.Array
type (§12.1.1) is a collection type, and since all array types derive from System.Array
, any array type expression is permitted in a foreach
statement. For single-dimensional arrays, the foreach
statement enumerates the array elements in increasing index order, starting with index 0
and ending with index Length
–
1
. For multi-dimensional arrays, the indices of the rightmost dimension are increased first.
A foreach
statement is executed as follows:
c
in the following. If c
is of a reference-type and has the value null
, a NullReferenceException
is thrown.c.GetEnumerator()
. The returned enumerator is stored in a temporary local variable, in the following referred to as e
. It is not possible for the embedded statement to access this temporary variable. If e
is of a reference-type and has the value null
, a NullReferenceException
is thrown.e.MoveNext()
.e.MoveNext()
is true
, the following steps are performed:
e.Current
, and the value is converted to the type of the iteration variable by an explicit conversion (§6.2). The resulting value is stored in the iteration variable such that it can be accessed in the embedded statement.continue
statement), another foreach
iteration is performed, starting with the step above that advances the enumerator.e.MoveNext()
is false
, control is transferred to the end point of the foreach
statement.Within the embedded statement of a foreach
statement, a break
statement (§8.9.1) may be used to transfer control to the end point of the foreach
statement (thus ending iteration of the embedded statement), and a continue
statement (§8.9.2) may be used to transfer control to the end point of the embedded statement (thus executing another iteration of the foreach
statement).
The embedded statement of a foreach
statement is reachable if the foreach
statement is reachable. Likewise, the end point of a foreach
statement is reachable if the foreach
statement is reachable.