I am trying to get my head around, what happens here ? What sort of code does the compiler produce?
public static void vc()
{
var listActions = new List<Action>();
foreach (int i in Enumerable.Range(1, 10))
{
listActions.Add(() => Console.WriteLine(i));
}
foreach (Action action in listActions)
{
action();
}
}
static void Main(string[] args)
{
vc();
}
output:
10
10
..
10
According to this, a new instance of ActionHelper would be created for every iteration. So in that case, I would assume it should print 1..10.
Can someone give me some pseudo code of what the compiler is doing here ?
Thanks.
In this line
the variable
i, is captured, or if you wish, created a pointer to the memory location of that variable. That means that every delegate got a pointer to that memory location. After this loop execution:for obvious reasons
iis10, so the memory content that all pointers present inAction(s) are pointing, becomes 10.In other words,
iis captured.By the way, should note, that according to Eric Lippert, this “strange” behaviour would be resolved in
C# 5.0.So in the
C# 5.0your program would print as expected:EDIT:
Can not find Eric Lippert’s post on subject, but here is another one:
Closure in a Loop Revisited