哪个静态类首先初始化?

Fre*_*ood 5 .net c# initialization static-classes

如果我们的项目中还有一个静态类,那么哪个静态类首先初始化?

例如:下面的代码给出了null异常.

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());
        }
    }
Run Code Online (Sandbox Code Playgroud)

如果你注意,你会看到如果First类将自己初始化,那么secondArrayfield Second将为null.但是如果Second类首先初始化,那么Secondclass firstArray将为null.我试图告诉哪个初始化首先产生不同的结果.

我认为这是关于我的项目的抽象问题.我在试图理解为什么会得到意想不到的结果时遇到它.

Jon*_*eet 10

First将开始初始化,分配firstArray,然后注意它需要Second初始化,以获得初始值secondArray.

Second将开始初始化,然后注意它需要首先进行初始化.但是,CLR会注意到First 已经在当前线程中初始化,因此它不会阻塞.Second初始化将完成,然后First的初始化将完成.

幸运的是,Second已经分配了需要的字段,因此发生了"正确的事情".

如果First 实际上首先开始初始化,这一切都很好.但是,由于这两个类都没有静态构造函数,因此可能Second会首先开始初始化...然后它将开始初始化First,这将发现Second已经初始化并获取Second.secondArray当前值(null)First.secondArray.这将是一件坏事.请注意,没有静态构造函数的类型的初始化时序在.NET 4中已经改变 - 不是以破坏规范的方式,而是可能以现有代码破坏的方式.

如果同时FirstSecond有静态构造函数,那么First将首先初始化,因为这是第一类Main接触.

答案的道德:不要这样做.相互引用的类型初始化器非常容易出错.再举一个例子,请参阅Eric Lippert和Neal Gafter的NDC 2010演讲,"C#Puzzlers",可以在NDC视频页面上观看.