我已经阅读了相关的C#语言规范(v5.0),但我找不到与我看到的内容相关的部分。
如果你运行下面的代码,你会看到下面的输出,这正是我期望的:
输出结果为:
这正是我预期的输出结果。特别需要注意的是,即使方法 F() 使用参数 "Init A.U" 执行时,一旦遇到 B.Y 引用,它就会再次被调用(中断,如果你喜欢这么说),导致 B 的静态初始化器执行。一旦 B 的静态构造函数完成,我们就会再次返回到 A.U 对 F() 的调用,这解释了为什么 B.Y 被设置为 6 然后又变成了 2。因此,希望大家都能理解这个输出结果。
以下是我不理解的部分:如果您注释掉 B 的静态构造函数,那么您将看到以下输出结果:
C#规范(v5.0)的10.5.5.1和10.12节指出,当“类的任何静态成员被引用”时,将触发A的静态构造函数(及其静态初始化器)执行。然而,在这里我们从F()内部引用了A.X,但A的静态构造函数没有被触发(因为它的静态初始化器没有运行)。
由于A有一个静态构造函数,我期望这些初始化器会运行(并中断)对F()的“Init B.R”调用,就像B的静态构造函数在一开始的“Init A.U”调用中中断了对A的F()调用一样。
有人能解释一下吗?表面上看起来似乎违反了规范,除非规范的其他部分允许这样做。
谢谢
如果你运行下面的代码,你会看到下面的输出,这正是我期望的:
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 A.U" 执行时,一旦遇到 B.Y 引用,它就会再次被调用(中断,如果你喜欢这么说),导致 B 的静态初始化器执行。一旦 B 的静态构造函数完成,我们就会再次返回到 A.U 对 F() 的调用,这解释了为什么 B.Y 被设置为 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()内部引用了A.X,但A的静态构造函数没有被触发(因为它的静态初始化器没有运行)。
由于A有一个静态构造函数,我期望这些初始化器会运行(并中断)对F()的“Init B.R”调用,就像B的静态构造函数在一开始的“Init A.U”调用中中断了对A的F()调用一样。
有人能解释一下吗?表面上看起来似乎违反了规范,除非规范的其他部分允许这样做。
谢谢
Test.F
需要加载B的类型信息。 - Mike Zboray