Было ли изменено использование переменных foreach в С# 5?

В этом ответе qaru.site/info/8243/... Эрик Липперт говорит, что "FYI мы, скорее всего, исправим это в следующей версии С#, это главная больная точка для разработчики" в отношении того, как петли foreach используют переменную.

В следующей версии каждый раз, когда вы запускаете цикл "foreach", мы генерируем новую переменную цикла, а не каждый раз закрываем одну и ту же переменную. Это "нарушение", но в подавляющем большинстве случаев "перерыв" будет исправлять, а не вызывать ошибки.

Я не смог найти ничего, что указывало бы, что это изменение уже сделано. Есть ли какие-либо признаки того, что так будет работать цикл foreach в С# 5?

Ответы

Ответ 1

Это изменение языка С#, а не .NET framework. Поэтому он влияет только на код, скомпилированный под С# 5.0, независимо от версии .NET framework, на которой будет выполняться этот код.

С# 5.0

В разделе 8.8.4 спецификации четко указано, что это изменение было сделано. В частности, на стр. 249 спецификации С# 5.0 указано:

foreach (V v in x) embedded-statement

затем расширяется до:

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

И позже:

Размещение v внутри цикла while важно для того, как оно захваченных любой анонимной функцией, происходящей в погруженное утверждение.

С# 4.0

Это изменение спецификации ясно при сравнении с спецификацией С# 4.0, которая указывает (опять же, в разделе 8.8.4, но на этот раз, стр. 247):

foreach (V v in x) embedded-statement

затем расширяется до:

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

Обратите внимание, что переменная v объявляется вне цикла, а не внутри, как в С# 5.0.

Примечание

Вы можете найти спецификацию С# в папке установки Visual Studio под VC#\Specifications\1033. Это относится к VS2005, VS2008, VS2010 и VS2012, предоставляя вам доступ к спецификациям для С# 1.2, 2.0, 3.0, 4.0 и 5.0. Вы также можете найти спецификации в MSDN, выполнив поиск C# Specification.