静态初始化继承的静态成员

car*_*ett 6 c# generics inheritance static-members

考虑这个示例代码:

public class A<T> 
{
    public static T TheT { get; set; }
}
public class B : A<string>
{
    static B() {
        TheT = "Test";
    }
}

public class Program {
    public static void Main(String[] args) {
        Console.WriteLine(B.TheT);
    }
}
Run Code Online (Sandbox Code Playgroud)

B.TheT是null.但是,更改Main方法如下:

public static void Main() {
    new B();
    Console.WriteLine(B.TheT);
}
Run Code Online (Sandbox Code Playgroud)

B.TheT正如预期的那样是"测试".我可以理解这会强制静态构造函数运行,但为什么第一种情况不会发生这种情况呢?

我试着阅读规范,引起了我的注意(§10.12):

[...]静态构造函数的执行由应用程序域中发生的以下第一个事件触发:

•[...]

•引用类类型的任何静态成员.

我对此的解释是,由于TheT不是其成员B,静态构造函数B不会被强制运行.它是否正确?

如果这是正确的,我怎么能最好B指定如何初始化TheT

Jon*_*eet 5

A.TheT是"测试",正如预期的那样.我可以理解这会强制静态构造函数运行,但为什么第一种情况不会发生这种情况呢?

基本上,你还没有真正引用B.如果你查看IL,我想你会发现你的代码实际上相当于:

public static void Main(String[] args) {
    Console.WriteLine(A<string>.TheT);
}
Run Code Online (Sandbox Code Playgroud)

编译器的工作指出,这是真的,你的意思的成员,即使你写B.TheT.

如果这是正确的,我怎么能最好让A指定如何初始化TheT?

我会尽量避免这样做,说实话......但你总是可以添加一个静态方法B:

public static void Initialize() {
    // Type initializer will be executed now.
}
Run Code Online (Sandbox Code Playgroud)

  • @carlpett:不,我不知道这样做的简单方法,坦率地使用像这样的静态初始化*通常*设计闻到IMO. (2认同)