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

时间:2017-01-16 12:55:40

标签: c# .net oop clr

我遇到了 this 链接,找到了以下代码段。我很想尝试使用代码片来获得不确定的输出。

以下代码段:

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

然而,出于某种原因,我总是得到第二个输出。无论我运行/重建/构建多少次。

有人可以解释一下:

  1. 为什么只有B级先被执行?如果我将通话转为 ' A.X,B.Y' ,然后只有A类首先被执行。
  2. 如何模拟不确定行为?

1 个答案:

答案 0 :(得分:0)

  

为什么只有B类首先被执行?

该规范说两个输出均有效。但是,将编译器和运行时(例如,在.Net Framework 4.7上运行的C#7.0的编译器)进行特定组合可以决定更严格和始终如一。

您使用的组合似乎决定首先初始化首先使用的类的静态字段,并按照规范接受该操作。

  

如何模拟不确定的行为?

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

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