Just got an interview in which I had to explain the following code:
private static int s = 1;
private static async Task Main(string[] args)
{
var tasks = new List<Task>();
Action a = () => s++;
tasks.Add(Task.Factory.StartNew(a));
tasks.Add(Task.Factory.StartNew(a));
tasks.Add(Task.Factory.StartNew(a));
tasks.Add(Task.Factory.StartNew(a));
await Task.WhenAll(tasks);
Console.WriteLine(s);
}
And at a first glance, I have answered that s
will 1
because of the closure mechanism and creating an additional class to encapsulate the field s
and work on it in the local scope just like in the code:
private static async Task Main(string[] args)
{
var tasks = new List<Task>();
Action a = GiveMeAction();
tasks.Add(Task.Factory.StartNew(a));
tasks.Add(Task.Factory.StartNew(a));
tasks.Add(Task.Factory.StartNew(a));
tasks.Add(Task.Factory.StartNew(a));
await Task.WhenAll(tasks);
}
public static Action GiveMeAction()
{
int i = 1;
return () => Console.WriteLine(++i);
}
Since closure will be translated as something like that:
[CompilerGenerated]
private sealed class <>c__DisplayClass8_0
{
// Fields
public int i;
// Methods
internal void <MyClosureCreationMethod>b__0()
{
int i = this.i;
this.i = i + 1;
}
}
The value will be passed by value. My question is: why the static field s
is changing globally and not locally in <>c__DisplayClass8_0
?