Take a look this snippet of the code
List<Action> actions = new List<Action>();
for (int variable = 0; variable < 5; ++variable)
{
int myLocalVariable = variable;
actions.Add(() => Console.WriteLine(myLocalVariable));
}
actions.ForEach(s => s.Invoke());
Console.ReadLine();
The output is 0 1 2 3 4
Looking at the IL code I tend to think that compiler creates only one instance of myLocalVariable. That fact also confirms good practice to use local variables inside loop.
So how does delegate inside actions.Add() store "up to date" version of the loop variable.
Looking at the IL code I tend to think that compiler creates only one instance of myLocalVariable.
Nope. The C# language specification makes it clear that the variable is instantiated on each iteration of the loop - so there's a separate variable for each iteration, and they're captured separately.
From section 7.5.15.2 of the C# 5 specification:
A local variable is considered to be instantiated when execution enters the scope of the variable. For example, when the following method is invoked, the local variable x is instantiated and initialized three times—once for each iteration of the loop.
static void F() { for (int i = 0; i < 3; i++) { int x = i * 2 + 1; ... } }
However, moving the declaration of x outside the loop results in a single instantiation of
x
...
When not captured, there is no way to observe exactly how often a local variable is instantiated—because the lifetimes of the instantiations are disjoint, it is possible for each instantation to simply use the same storage location. However, when an anonymous function captures a local variable, the effects of instantiation become apparent.
See more on this question at Stackoverflow