Вы просили ссылку на спецификацию;соответствующее расположение - раздел 8.8.4, в котором говорится, что цикл «foreach» эквивалентен:
V v;
while (e.MoveNext()) {
v = (V)(T)e.Current;
embedded-statement
}
Обратите внимание, что значение v объявлено вне цикла while, и поэтому существует одна переменная цикла,Затем это закрывается лямбда-выражением.
ОБНОВЛЕНИЕ
Поскольку многие сталкиваются с этой проблемой, команда разработчиков и проектировщиков C # изменила C # 5, чтобы иметь эту семантику :
while (e.MoveNext()) {
V v = (V)(T)e.Current;
embedded-statement
}
Который затем ведет себя ожидаемым образом - вы каждый раз закрываете новую переменную.Технически это серьезное изменение, но, надеюсь, количество людей, которые зависят от странного поведения, которое вы испытываете, очень мало.
Помните, что C # 2, 3 и 4 теперь несовместимы с C # 5 в этом отношении.Также обратите внимание, что изменение относится только к foreach
, а не к for
петлям.
Подробнее см. http://ericlippert.com/2009/11/12/closing-over-the-loop-variable-considered-harmful-part-one/.
Состояния абергмейера Commenter:
C # - единственный язык с таким странным поведением.
Это утверждение категорически неверно .Рассмотрим следующий код JavaScript:
var funcs = [];
var results = [];
for(prop in { a : 10, b : 20 })
{
funcs.push(function() { return prop; });
results.push(funcs[0]());
}
abergmeier, не могли бы вы догадаться, каково содержание results
?