In old compiler versions, the code from the problem will be transformed in the following code:
public void Run()
{
var actions = new List<Action>();
DisplayClass c1 = new DisplayClass();
foreach (int i in Enumerable.Range(1, 3))
{
с1.i = i;
list.Add(c1.Action);
}
foreach (Action action in list)
action();
}
private sealed class DisplayClass
{
public int i;
public void Action()
{
Console.WriteLine(i);
}
}
Thus, all elements from the list refer to same delegate. So, we will see 3 same values in the console, they will equal the last value of i
.
Some breaking changes were in new compiler versions. The new version of the code:
public void Run()
{
var actions = new List<Action>();
foreach (int i in Enumerable.Range(1, 3))
{
DisplayClass c1 = new DisplayClass();
с1.i = i;
list.Add(c1.Action);
}
foreach (Action action in list)
action();
}
private sealed class DisplayClass
{
public int i;
public void Action()
{
Console.WriteLine(i);
}
}
Now, each element of the list refers to own delegate, all printed values will be different.
Mono compiler 2.4.4 : 3 3 3
Mono compiler 3.10.0 : 1 2 3
Mono compiler 3.10.0 langversion=4 : 1 2 3
MS compiler 3.5.30729.7903 : 3 3 3
MS compiler 4.0.30319.1 : 3 3 3
MS compiler 4.0.30319.33440 : 1 2 3
MS compiler 4.0.30319.33440 langversion=4 : 1 2 3