Has foreach’s use of variables been changed in C# 5?

This is a change to the C# language, not the .NET framework. Therefore, it only affects code compiled under C# 5.0, regardless of the .NET framework version on which that code will execute.

C# 5.0

Section 8.8.4 of the specification makes it clear that this change has been made. Specifically, page 249 of the C# 5.0 specification states:

foreach (V v in x) embedded-statement

is then expanded to:

{
    E e = ((C)(x)).GetEnumerator();
    try {
        while (e.MoveNext()) {
            V v = (V)(T)e.Current;
            embedded-statement
        }
    }
    finally {
        … // Dispose e
    }
}

And later:

The placement of v inside the while loop is important for how it is
captured by any anonymous function occurring in the
embedded-statement.

C# 4.0

This change to the specification is clear when comparing with the C# 4.0 specification which states (again, in section 8.8.4, but this time, page 247):

foreach (V v in x) embedded-statement

is then expanded to:

{
    E e = ((C)(x)).GetEnumerator();
    try {
        V v;
        while (e.MoveNext()) {
            v = (V)(T)e.Current;
            embedded-statement
        }
    }
    finally {
        … // Dispose e
    }
}

Note that the variable v is declared outside the loop instead of inside, as it is with C# 5.0.

Note

You can find the C# specification in the installation folder of Visual Studio under VC#\Specifications\1033. This is the case for VS2005, VS2008, VS2010 and VS2012, giving you access to specifications for C# 1.2, 2.0, 3.0, 4.0 and 5.0. You can also find the specifications on MSDN by searching for C# Specification.

Leave a Comment