0

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?

Pawel
  • 525
  • 3
  • 16
  • 1
    a static field is unique, there is only that reference, it is a singleton. – bto.rdz Apr 12 '21 at 00:14
  • 1
    That the variable is a static field is actually a red herring. The whole point of a closure over a variable is that, if necessary, the variable is lifted from its nominal context so that its lifetime is extended to accommodate the closure. The exact same behavior would have happened had the variable been a local variable, because there's still only one variable. See duplicate. Now, it's true that because the variable's lifetime already exceeds that of the closure, the compiler doesn't need to do any extra work to close over the variable. But either way, there's only ever one variable. – Peter Duniho Apr 12 '21 at 00:36
  • Nice. Good explanation. Thanks – Pawel Apr 12 '21 at 12:29

1 Answers1

-1

Static class properties can be modified unlike public static readonly int i = 1 which is immutable outside of the constructor. Since a static property is only associated with the type and types are defined during compilation, it can be considered "global" during runtime

Bugbeeb
  • 2,021
  • 1
  • 9
  • 26