我已经做了一些搜索,并且我认为以下代码可以保证产生输出:
B.X = 7 B.X = 0 A.X = 1 A = 1, B = 0 static class B { public static int X = 7; static B() { Console.WriteLine("B.X = " + X); X = A.X; Console.WriteLine("B.X = " + X); } } static class A { public static int X = B.X + 1; static A() { Console.WriteLine("A.X = " + X); } } static class Program { static void Main() { Console.WriteLine("A = {0}, B = {1}", A.X, B.X); } }
我已经运行了无数次,并且始终在代码部分上方获得输出;我只是想确认它会改变吗?即使从文字上讲,班级A和班级也要B重新安排?
A
B
是否保证首次使用静态对象会触发其静态成员的初始化,然后实例化其静态构造函数?对于此程序,A.X在main中使用将触发的初始化,然后A.X依次初始化B.X,然后B()在完成初始化后A.X继续进行A()。最后,Main()将输出A.X和BX`。
A.X
B.X
B()
A()
Main()
直接来自ECMA-334:
17.4.5.1: “ 如果类中存在静态构造函数(第17.11节),则在执行该静态构造函数之前立即执行 静态字段初始化程序 。 否则,将在与实现相关的时间执行静态字段初始化程序 。 首先使用该类的静态字段。”
和:
17.11: 静态构造函数的执行由在应用程序域内发生的以下第一个事件触发: 创建该类的实例。 引用了该类的任何静态成员。 如果类包含开始执行的Main方法(第10.1节),则该类的静态构造函数将在调用Main方法之前执行。 如果类包含带有初始化程序的任何静态字段,则在执行静态构造函数之前,将按文本顺序执行这些初始化程序(第17.4.5节)。
17.11: 静态构造函数的执行由在应用程序域内发生的以下第一个事件触发:
如果类包含开始执行的Main方法(第10.1节),则该类的静态构造函数将在调用Main方法之前执行。 如果类包含带有初始化程序的任何静态字段,则在执行静态构造函数之前,将按文本顺序执行这些初始化程序(第17.4.5节)。
因此顺序为:
static A()
static B()
B.X = 7
X
B.X = 0
B.X+1
A.X = 1
Main
它实际上在标准中对此进行了评论:
17.4.5: 可以在默认值状态下观察带有变量初始化器的静态字段。 但是,强烈不建议使用此样式。