Sunday, April 25, 2010

.Net static constructors

Following are some links related to static constructor and beforeFieldInit flag
Following are some key points:
  • If your class does not have a static constructor and has static fields then the class is marked with 'beforefieldinit' attribute
    • This means that the static fields will be initialized any time before any static method or instance method is accessed e.g. if you put a code in a method say Method1() which access a static variable from above class then your static variable can be initialized as soon as you enter Method1(). (This is an example and based on my observation. As per documentation the initializer for static variable can be called at assembly load also or not at all)
  • If your class has a static constructor and has static fields then the class is not marked with 'beforefieldinit' attribute.
    • This means that the static ctor will be called before any static or instance field is accessed. This means compiler puts a check before every call of the class to check if static ctor is called which is expensive. Also, with this in the previous example the static variable will not be initialized as soon as you enter Method1() but it will be initialized on first call.
Let's check the output with and without static constructor foe following class:

    public class MyClass
    {
        public static string Variable01 = GetVariableValue();

        /*
        static MyClass()
        {
            Console.WriteLine("MyClass static ctor called...");
        }*/

        private static string GetVariableValue()
        {
            Console.WriteLine("MyClass.GetVariableValue called...");

            return "Variable1 value";
        }
    }


The method which calls the above class is as follows:
        private static void StaticTest()
        {
            Console.WriteLine("StaticTest called...");

            Console.WriteLine("MyClass.Variable01 = [{0}]", MyClass.Variable01);
        }


Without static constructor the output is as follows:


MyClass.GetVariableValue called...
StaticTest called...
MyClass.Variable01 = [Variable1 value]


Note that the static variable is initialized as soon as you enter the method i.e. "MyClass.GetVariableValue called..." is before "StaticTest called..."

If you use static constructor then the output is as follows:

StaticTest called...
MyClass.GetVariableValue called...
MyClass static ctor called...
MyClass.Variable01 = [Variable1 value]



Here the "StaticTest called..." is displayed first then the static variable initializer is called and then static ctor.

To conclude: Without static ctor your static variables are initialized before any calls to static or instance methods. But you won't get lazy initialization. with static ctor you get lazy initialization but since compiler puts a check the calls are expensive.

No comments:

Post a Comment