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.
谁能解释一下:
- 为什么只有 Class B 先被执行?如果我将呼叫撤消为
'A.X, B.Y',那么只有Class A先被执行。
- 如何模拟不确定的行为?
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),以找到所有可能的初始化顺序,然后选择一个随机.
我遇到了 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.
谁能解释一下:
- 为什么只有 Class B 先被执行?如果我将呼叫撤消为 'A.X, B.Y',那么只有Class A先被执行。
- 如何模拟不确定的行为?
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),以找到所有可能的初始化顺序,然后选择一个随机.