开发者

Which static class initializes first?

Which static class initializes first if we have one more static classes in our project?

For example: Below code gives null exception.

class Program
    {
        static void Main(string[] args)
        {
            First.Write();
            Second.Write();
        }
    }
    static class First
    {
        public static int[] firstArray = new int[20];
        public static int[] secondArray = Second.secondArray;
        public static void Write()
        {
            Console.WriteLine(firstArray.ToString());
            Console.WriteLine(secondArray.ToString());
        }
    }
    static class Second
    {
        public static int[] firstArray = First.firstArray;
        public 开发者_高级运维static int[] secondArray = new int[30];
        public static void Write()
        {
            Console.WriteLine(firstArray.ToString());
            Console.WriteLine(secondArray.ToString());
        }
    }

If you pay attention, you will see that if First class will initialize itself so secondArray field of Second would be null. But if Second class would initialize first so Second class firstArray would be null. I am trying to tell that which initialize first makes different results.

I think that it is abstract question about my project. I encounter it while trying to understand why I am getting unexpected results.


First will begin to initialize, assign firstArray, then notice that it requires Second to be initialized in order to get the initial value of secondArray.

Second will start initializing, and then notice that it requires First to be initialized. However, the CLR will then notice that First is already initializing in the current thread, so it won't block. Second's initialization will complete, and then First's initialization will complete.

Fortunately, the field that Second needs has already been assigned, so the "right thing" happens.

That's all very well if First actually starts initializing first. However, as neither of the classes has a static constructor, it's possible that Second will start to initialize first... it would then start to initialize First, which would spot that Second is already initializing and take Second.secondArray's current value (null) for First.secondArray. This would be a Bad Thing. Note that the initialization timing for types without static constructors has changed in .NET 4 - not in a spec-breaking way, but possibly in an existing-code-breaking way.

If both First and Second had static constructors, then First would be initialized first, as that's the first class that Main touches.

Moral of the answer: don't do this. Type initializers which refer to each other are very error prone. For another example, see Eric Lippert and Neal Gafter's NDC 2010 talk, "C# Puzzlers" which can be viewed on the NDC video page.


I don't believe there is any guarantee as to which static type is initialised first. To ensure fields are initialised properly this way, you'd need to add a static constructor, e.g.:

static class Second
{
    public static int[] firstArray = First.firstArray;
    public static int[] secondArray = new int[30];

    static Second() { }

    public static void Write()
    {
        Console.WriteLine(firstArray.ToString());
        Console.WriteLine(secondArray.ToString());
    }
}

Now, when you run the same thing again, it works...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜