C#中的静态字段初始化顺序

Static field initialization Order in C#

我遇到了 this link 并找到了以下代码段。我很好奇尝试使用代码片段来获得不确定的输出。

以下片段:

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

可能会产生输出:

Init A

Init B

1 1

或输出:

Init B

Init A

1 1

但是,出于某种原因,我总是得到第二个输出。不管我多少次运行/rebuild/build.

谁能解释一下:

  1. 为什么只有 Class B 先被执行?如果我将呼叫撤消为 'A.X, B.Y',那么只有Class A先被执行。
  2. 如何模拟不确定的行为?

Why only Class B is getting executed first?

规范说两个输出都是有效的。但是编译器和运行时的特定组合(例如 .Net Framework 4.7 上的 C# 7.0 运行 的编译器)可以决定更严格并且行为一致。

您使用的组合似乎决定首先初始化首先使用的 class 的静态字段,根据规范,这样做是可以接受的。

How can I simulate the uncertain behavior?

同样,规范不需要任何不确定性。

如果您真的想让它以这种方式运行,您可以修改现有的 .Net 运行时(如 CoreCLR、Mono 或 DotNetAnywhere),以找到所有可能的初始化顺序,然后选择一个随机.