Static constructor is called before any static members are referenced

放肆的年华 提交于 2019-12-06 05:17:35

Consider this class:

public static class TestStatic
{
    public static int SomeValue = GetValue();

    static TestStatic()
    {
        Console.WriteLine("Constructor");
    }

}

And this supporting method:

public static int GetValue()
{
    Console.WriteLine("GetValue");
    return 5;
}

If you run this code:

Console.WriteLine(TestStatic.SomeValue);

The output you will get is:

GetValue
Constructor
5

So you can see that both of the statements you posted are correct. The constructor is called before the static member (SomeValue) is referenced and the static field initialiser is called before the constructor.

Both of the statements you have mentioned are true and are in sync with each other. I am not sure why you think they are contradicting.

The order of execution is as follows:

  1. Static fields with initializers.
  2. Static Constructor.

The above is as per your second statement. The first statement just mentions when these actions are performed i.e. before:

  1. The first instance of the class is created.
  2. Any static members are referenced.

In fact, the above conditions can be taken as guaranteed for static constructors that the static field initializers will be executed and static constructor will be called before any of the two happens (statement 1).

The C# specification clearly mentions:

The static constructor for a class executes at most once in a given application domain. The execution of a static constructor is triggered by the first of the following events to occur within an application domain: An instance of the class is created. Any of the static members of the class are referenced. If a class contains the Main method (Section 3.1) in which execution begins, the static constructor for that class executes before the Main method is called. If a class contains any static fields with initializers, those initializers are executed in textual order immediately prior to executing the static constructor.

Just to add on, since you have highlighted -

before the first instance is created or any static members are referenced.

This just means that it is possible to refer to a static member of a class even before creating an instance of that class. So, even in that case, the static constructor will be called before accessing the static member.

If you see DavidG's code in his answer, even though the class is not being instantiated, but one of the static members is being referenced, still the static field initialization takes place before that which is followed by static constructor execution.

Example:

public static class Test
{
    public static int i = 10;
    public static int j = new Func<int>(() => { 
            Console.WriteLine("Static field initializer called."); return 20; 
        })();
    static Test()
    {
        Console.WriteLine("Static Constructor called.");
    }
}

Now if you execute:

Console.WriteLine(Test.i);

You get the following output:

Static field initializer called.

Static Constructor called.

10

The reason for such a behavior (and it's by design) is that the initialization of static fields actually happens as part of the static constructor. The compiler prepends the static constructor logic with all the expressions you have for static fields' initializers.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!