一个不应该运行的静态初始化程序

Tom*_*ter 1 c# static initializer

之前我在同一代码的Debug和Release版本之间发布了一个关于静态初始化器和不同输出的问题.我确定Release版本从Debug构建产生了不同的输出(实际上它没有产生输出),因为一个DebuggableAttribute设置允许JIT优化器消除Release版本中的输出.

我想的越多,它就越困扰我.在我进一步讨论之前,让我展示我原始发布的代码和Debug构建中产生的输出:

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

此代码的输出(当使用Debug构建运行时)是这样的:

In Initialize() :: Assigning a, name=, returning 1
In Initialize() :: Assigning b, name=, returning 2
In Initialize() :: Assigning c, name=Fred, returning 3
Run Code Online (Sandbox Code Playgroud)

我完全理解JITter能够优化输出,我理解为什么会这样做,所以我不是要求任何人解决Debug和Release版本之间的差异.

困扰我的是为什么 任何输出应该出现在第一位.该类没有静态c'tor(强制静态初始化程序可以运行),没有对类外部的静态字段的引用,并且该类从未实例化.我要说的是,这个代码产生的输出应该永远不会产生,甚至不是由Debug构建产生的,至少从我对语言规范的理解来看.

我一直在研究C#规范的各个部分,我找不到任何说静态初始化器应该为下面显示的代码运行,无论它是为Debug还是Release编译的.

任何人都可以解释为什么这段代码应该产生输出以及语言规范的哪些部分适用?

谢谢.

Blo*_*ard 5

该行为定义为依赖于实现:

10.4.5.1静态字段初始化

如果类中存在静态构造函数(第10.11节),则在执行该静态构造函数之前立即执行静态字段初始值设定项.否则,静态字段初始化器在第一次使用该类的静态字段之前的实现相关时间执行.

我猜它会使调试更容易早期初始化它们.

  • 没有*需要*,但没有要求*不*运行它们.任何时候"允许在第一次使用静态场之前".由于没有使用静态字段,任何时候都可以. (5认同)