【发布时间】:2017-05-31 07:45:15
【问题描述】:
我遇到了 this 链接并找到了下面的 sn-p。我很想尝试 sn-p 以获得不确定的输出。
下面的sn-p:
using System;
class Test
{
static void Main()
{ // Breakpoint here is skipped and control goes to Class B then Class A
// Why control is always going to Class B first?
Console.WriteLine("{0} {1}", B.Y, A.X);
}
public static int F(string s) {
Console.WriteLine(s);
return 1;
}
}
class A
{ //
public static int X = Test.F("Init A");
}
class B
{ // Debugging always starts here.
public static int Y = Test.F("Init B");
}
可能会产生以下输出:
初始化A
初始化 B
1 1
或输出:
初始化 B
初始化A
1 1
但是,出于某种原因,我总是得到第二个输出。无论我运行/重建/构建多少次。
谁能解释一下:
- 为什么只有 B 类首先被执行?如果我将呼叫反转为 'A.X, B.Y',那么只有 A 类首先被执行。
- 如何模拟不确定的行为?
【问题讨论】:
-
如果您只是在同一台机器上针对同一个 CLR 运行,您不太可能看到变化。存在不确定性和灵活性,例如JIT 编译器的不同实现。
-
如果执行顺序与代码所需的顺序相关,我不会感到惊讶 - 如果不需要,为什么要初始化某些东西。如果您使用“B.Y,B.Y”调用 - 那么我希望 A.X 未初始化。
-
完整阅读您的链接我看到的措辞是这样的:“否则,静态字段初始化程序在第一次使用该类的静态字段之前在与实现相关的时间执行。 " 和以后的"它们只被限制在引用这些字段之前出现"。所以实际上它的意思是必须在首次使用之前完成初始化并且由实现来决定何时 - 这与说行为不确定并且可能以任何顺序发生是不同的。