I read different articles regarding this theme Eric Lippert's blog and other here and know why this two code will work differently
int[] values = { 7, 9, 13 };
List<Action> f = new List<Action>();
foreach (var value in values)
f.Add( () => Console.WriteLine("foreach value: " + value));
foreach (var item in f)
item();
f = new List<Action>();
for (int i = 0; i < values.Length; i++)
f.Add(() => Console.WriteLine("for value: " + ((i < values.Length) ? values[i] : i)));
foreach (var item in f)
item();
But I didn't find clean explanation why eventually (begin from compiler c# version 5) was decided to made " the foreach loop variable will be logically inside the body of the loop, and therefore closures will get a fresh copy every time." Because the old realization give a more freedom to use the closures Lambda ("by value or by ref") but demanded from programmer to use it carefully and if you needed the current implementation from foreach you should was used the following code:
foreach(var v in values)
{
var v2 = v;
funcs.Add( ()=>v2 );
}
QUESTIONS:
Q1. I wonder why in the end it was decided to change the implementation of foreach (pros and cons I read, it was 50/50 Eric Lippert's blog)?
Q2. In the case of a "for" loop, it's a value that falls outside the loop's operating range (this creates a very specific situation where the lambda gets a value that you'll never get in the loop), why is it "out of control" because it's a very error prone situation ? (question number 2 is more rhetorical therefore can be skipped)
Additional explanation (for Q1) It would be interesting to know the reasons why this implementation was chosen - why the developers of C#, starting with version 5, changed the principles of closure for the foreach loop. Or why they did it for the foreach loop but didn't do it for the for.