我已经浏览了 C# Language Spec (v5.0) 的相关部分,但我找不到与我所看到的内容相关的部分。
如果你运行下面的代码,你会看到下面的输出,这是我所期望的:
using System;
class Test {
static int count = 0;
static void Main() {
Console.WriteLine("In Main(), A.X=" + A.X);
}
public static int F(string message) {
Console.WriteLine(message);
A.X = ++count;
Console.WriteLine("\tA.X has been set to " + A.X);
B.Y = ++count;
Console.WriteLine("\tB.Y has been set to " + B.Y);
return 999;
}
}
class A {
static A() { }
public static int U = Test.F("Init A.U");
public static int X = Test.F("Init A.X");
}
class B {
static B() { }
public static int R = Test.F("Init B.R");
public static int Y = Test.F("Init B.Y");
}
输出是:
Init A.U
A.X has been set to 1
Init B.R
A.X has been set to 3
B.Y has been set to 4
Init B.Y
A.X has been set to 5
B.Y has been set to 6
B.Y has been set to 2
Init A.X
A.X has been set to 7
B.Y has been set to 8
In Main(), A.X=999
这正是我所期望的输出。特别注意,即使方法 F() 使用参数“Init AU”执行,一旦遇到对 BY 的引用,它也会再次调用(如果您愿意,可以中断),导致 B 的静态初始化程序执行。一旦 B 的静态构造函数完成,我们再次返回到 F() 的 AU 调用,这说明 BY 设置为 6,然后设置为 2。所以,希望这个输出对每个人都有意义。
这是我不理解的:如果您注释掉 B 的静态构造函数,这是您看到的输出:
Init B.R
A.X has been set to 1
B.Y has been set to 2
Init B.Y
A.X has been set to 3
B.Y has been set to 4
Init A.U
A.X has been set to 5
B.Y has been set to 6
Init A.X
A.X has been set to 7
B.Y has been set to 8
In Main(), A.X=999
C# 规范 (v5.0) 的第 10.5.5.1 和 10.12 节指示 A 的静态构造函数(及其静态初始化程序)在“引用类的任何静态成员”时触发执行。然而,这里我们从 F() 中引用了 AX,并且没有触发 A 的静态构造函数(因为它的静态初始化程序没有运行)。
由于 A 有一个静态构造函数,我希望这些初始化程序运行(并中断)对 F() 的“Init BR”调用,就像 B 的静态构造函数在我展示的“Init AU”调用中中断 A 对 F() 的调用一样一开始。
谁能解释一下?从表面上看,它看起来违反了规范,除非规范的其他部分允许这样做。
谢谢