Consider this code.
var values = new List<int> {123, 432, 768};
var funcs = new List<Func<int>>();
values.ForEach(v=>funcs.Add(()=>v));
funcs.ForEach(f=>Console.WriteLine(f()));//prints 123,432,768
funcs.Clear();
foreach (var v1 in values)
{
funcs.Add(()=>v1);
}
foreach (var func in funcs)
{
Console.WriteLine(func()); //prints 768,768,768
}
I know that the second foreach prints 768 3 times because of the closure variable captured by the lambda. why does it not happen in the first case?How does foreach
keyword different from the method Foreach
? Is it beacuse the expression is evaluated when i do values.ForEach
The difference is that in the
foreach
loop, you've got a single variablev1
which is captured. That variable takes on each value withinvalues
- but you're only using it at the end... which means we only see the final value each time.In your
List<T>.ForEach
version, each iteration introduces a new variable (the parameterf
) - so each lambda expression is capturing a separate variable, which never changes in value.Eric Lippert has blogged about this - but note that this behaviour may change in future versions of C#.
foreach
only introduces one variable. While the lambda parameter variable is "fresh" each time it is invoked.Compare with:
That is,
can be thought of as:
Happy coding.