Search code examples
c#.netconstructorstaticprogram-entry-point

Declaration order of types or members in c#


I am totally confused by some of the active discussions on declaration order of types or members in C#.

There is a trending question, what would be the output of this and why?

Scenario 1:

    class Program
    {

        static readonly int A = Method();
        static readonly int B = 42;
        static int Method() => B;

        static void Main()
        {
            Console.WriteLine(A); // 0
        }
    }

and if suppose, I update the above code and make it something like this:

Scenario 2:

    class Program
    {

        
        static readonly int B = 42;
        static int Method() => B;
        static readonly int A = Method();
        static void Main()
        {
            Console.WriteLine(A); // 42
        }
    }

The output of Scenario 1 is 0 against the output of Scenario 2 is 42. How this output is zero or 42?

I have checked few answers but aren't able to understand, how and why these answers are 0 and 42.

link 1 link 2


Solution

  • When you write this:

    class Program
    {
    
        static readonly int A = Method();
        static readonly int B = 42;
        static int Method() => B;
    
        static void Main()
        {
            Console.WriteLine(A); // 0
        }
    }
    

    The compiler will generate a static constructor for you, which assigns the initial values to your various fields. The order of these assignments matches the order that the fields are declared in:

    class Program
    {
    
        static readonly int A;
        static readonly int B;
    
        static Program()
        {
            A = Method();
            B = 42;
        }
    
        static int Method() => B;
    
        static void Main()
        {
            Console.WriteLine(A); // 0
        }
    }
    

    When the static constructor runs, it's fairly clear that Method() is executed, and A assigned to, before B is assigned to. Fields have an initial value of 0, before anything is assigned to them. So Method() will return 0.

    Follow the same logic for your second scenario, and you'll see how it's different.