哪个静态类首先初始化?

时间:2010-07-01 11:23:08

标签: c# .net 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());
        }
    }

如果您注意,您会看到如果First类会自行初始化,那么secondArray Second字段将为空。但是如果Second类首先初始化,那么SecondfirstArray将为空。我试图告诉哪个初始化首先产生不同的结果。

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

2 个答案:

答案 0 :(得分:10)

First将开始初始化,分配firstArray,然后注意它需要初始化Second才能获得secondArray的初始值。

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

幸运的是,已经分配了Second所需的字段,因此发生了“正确的事情”。

如果Second 实际上首先开始初始化,那就非常好了。但是,由于这两个类都没有静态构造函数,First可能会首先开始初始化...然后它会开始初始化Second,这会发现First是已经初始化并获取Second的{​​{1}}当前值(null)。这将是一件坏事。请注意,没有静态构造函数的类型的初始化时序为changed in .NET 4 - 不是以破坏规范的方式,而是可能以现有代码破坏的方式。

如果Second.secondArrayFirst.secondArray都有静态构造函数,那么First将首先被初始化,因为这是Second触及的第一个类。

答案的道德:不要这样做。相互引用的类型初始化器非常容易出错。再举一个例子,请参阅Eric Lippert和Neal Gafter的NDC 2010演讲,“C#Puzzlers”,可在NDC video page上查看。

答案 1 :(得分:0)

我不相信有关哪个静态类型首先被初始化的保证。要确保以这种方式正确初始化字段,您需要添加静态构造函数,例如:

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());
    }
}

现在,当你再次运行同样的东西时,它会起作用......