Замыкания в foreach и for
Почему при добавлении анонимных методов в делегат в цикле foreach, переменная i не замыкается и происходит вывод не последнего элемента массива 4 раза, а всех?
//D объявлен как delegate void D()
D func = Console.WriteLine;
foreach(var i in new [] { 1,2,3,4 })
{
func += () => Console.WriteLine(i);
}
func();
При этом, если переписать ту же операцию под цикл for
//D объявлен как delegate void D()
D func = Console.WriteLine;
for (var i = 0; i < 4; i++)
{
func += () => Console.WriteLine(i);
}
func();
То все ожидаемо - четверка выводится 4 раза
Ответы (2 шт):
Спасибо tym32167
Цитата из статьи на Хабре - Замыкания на переменных цикла в C# 5:
В C# 5.0 решили изменить цикл foreach таким образом, чтобы на каждой итерации цикла переменная i создавалась вновь. По сути, в предыдущих версиях языка C# в цикле foreach была лишь одна переменная цикла, а начиная с C# 5.0, используется новая переменная для каждой итерации
Потому что так и задумано: в современном C# на каждой итерации создаётся новая переменная, специально чтобы не было проблем с замыканиями.