[英]Static initialization of inherited static member
考虑这个示例代码:
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);
}
}
这里B.TheT
为空。 但是,更改Main
方法如下:
public static void Main() {
new B();
Console.WriteLine(B.TheT);
}
B.TheT
是预期的“测试”。 我可以理解这会强制静态构造函数运行,但为什么第一种情况不会发生这种情况呢?
我试着阅读规范,引起了我的注意(§10.12):
[...]静态构造函数的执行由应用程序域中发生的以下第一个事件触发:
•[...]
•引用类类型的任何静态成员。
我对此的解释是,由于TheT
是不是成员B
,静态构造函数B
不强制运行。 它是否正确?
如果这是正确的,我怎么能最好让B
指定如何初始化TheT
?
A.TheT是“测试”,正如预期的那样。 我可以理解这会强制静态构造函数运行,但为什么第一种情况不会发生这种情况呢?
基本上,你还没有真正引用过B
如果你查看IL,我想你会发现你的代码实际上相当于:
public static void Main(String[] args) {
Console.WriteLine(A<string>.TheT);
}
编译器的工作指出,这是真的你的意思是会员,即使你写B.TheT
。
如果这是正确的,我怎么能最好让A指定如何初始化TheT?
我会尽量避免这样做,说实话......但你总是可以向B
添加一个静态方法:
public static void Initialize() {
// Type initializer will be executed now.
}
静态构造函数在第一次访问之前调用,或者最迟在第一次访问时调用。 也就是说,你知道它是在第一次访问时调用的,但不是在多久之前调用的。 但是,如果不进行访问,则不会调用它。 因此,只有当它被调用时你才能控制它。
根据MSDN参考
静态构造函数用于初始化任何静态数据,或执行仅需执行一次的特定操作。 在创建第一个实例或引用任何静态成员之前自动调用它。
在第二种情况下称为静态构造函数,它将调用实际类型的静态构造函数,而不是派生函数的静态构造函数。 所以在你的情况下,它调用A<T> =>A<string>
的静态ctor,而不是 A
要证明此行为,请执行以下操作:
public class Base {
static Base() {
"Base static".Dump();
}
}
public class Derived : Base {
static Derived() {
"Derived static".Dump();
}
public static string temp = "Hello";
}
并打电话
Derived.temp.Dump();
你会得到:
Derived static
Hello
这是你在你的代码实际上做的,你接取派生类型A<string>
和它的默认构造函数静态调用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.