Замыкания в 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 шт):

Автор решения: Abskin

Спасибо tym32167
Цитата из статьи на Хабре - Замыкания на переменных цикла в C# 5:

В C# 5.0 решили изменить цикл foreach таким образом, чтобы на каждой итерации цикла переменная i создавалась вновь. По сути, в предыдущих версиях языка C# в цикле foreach была лишь одна переменная цикла, а начиная с C# 5.0, используется новая переменная для каждой итерации

→ Ссылка
Автор решения: Pavel Mayorov

Потому что так и задумано: в современном C# на каждой итерации создаётся новая переменная, специально чтобы не было проблем с замыканиями.

→ Ссылка