Login
Где найти старый компилятор для C# 4.0
821 просмотров
Перейти к просмотру всей ветки
in Antwort MrSanders 16.03.19 20:03, Zuletzt geändert 17.03.19 11:56 (dymanoid)
Изменение foreach элементарное, но сильно влияет на замыкания.
До 4.0 включительно, foreach разворачивался так:
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 } }
Начиная с 5.0, foreach разворачивается так:
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. Именно это и влияет на то, что происходит с замыканиями. В первом случае замыкание будет на одну переменную для всех итераций, во втором - множество замыканий на разные переменные в каждой итерации.
При этом сама переменная итерации v была и остаётся read-only во всех версиях языка. Это по спецификации, компилятор это гарантирует. Из кода выше этого не видно, потому что это реализовано не кодом, а компилятором. Если убрать эту проверку из компилятора, то технически переменную итерации можно изменять, код это позволяет.