早先我posted a question关于静态初始化器和相同代码的Debug和Release版本之间的不同输出。我确定Release版本从Debug构建产生了不同的输出(实际上它产生了 no 输出),因为DebuggableAttribute
设置允许JIT优化器消除Release版本中的输出。
我越是想到这一点,它就越困扰我。在我走得更远之前,让我展示我原始发布的代码和Debug build中产生的输出:
using System;
class Test {
static int value = 0;
static int a = Initialize("Assigning a");
static int b = Initialize("Assigning b");
static String name = "Fred";
static int c = Initialize("Assigning c");
static int Initialize(String mssg) {
++value;
Console.WriteLine("In Initialize() :: {0}, name={1}, returning {2}", mssg, name, value);
return value;
} // Initialize()
static void Main() {
}// Main()
} // class Test
此代码的输出(使用Debug构建运行时)是:
In Initialize() :: Assigning a, name=, returning 1
In Initialize() :: Assigning b, name=, returning 2
In Initialize() :: Assigning c, name=Fred, returning 3
我完全理解JITter能够优化输出,我理解为什么会这样做,所以我不是要求任何人解决Debug和Release版本之间的差异。
让我烦恼的是为什么 任何输出应该首先出现。该类没有静态c'tor(强制静态初始化程序可以运行),没有对类外部的静态字段的引用,并且该类从未实例化。我要说的是,这个代码产生的输出应该永远不会产生,甚至不是由Debug构建产生的,至少从我对语言规范的理解来看。
我一直在研究C#规范的各个部分,我找不到任何说静态初始化器应该为下面显示的代码运行的东西,无论它是为Debug还是Release编译的。
有人可以解释为什么这段代码应该产生输出以及语言规范的哪些部分适用?
感谢。
答案 0 :(得分:5)
行为定义为依赖于实现:
10.4.5.1 Static field initialization
如果类中存在静态构造函数(第10.11节),则在执行该静态构造函数之前立即执行静态字段初始值设定项。 否则,静态字段初始值设定项在首次使用该类的静态字段之前的实现相关时间执行。
我猜它会使调试更容易早期初始化。