我有三个课程,Base
,Derived
和Final
。 Derived
Base
来自Final
,Derived
来自Derived
。这三个类都有一个静态构造函数。类Setup
作为名为Final.Setup
的公共静态方法。当我调用Derived
时,我希望所有三个静态构造函数都被执行,但只有 abstract class Base
{
static Base()
{
System.Console.WriteLine ("Base");
}
}
abstract class Derived : Base
{
static Derived()
{
System.Console.WriteLine ("Derived");
}
public static void Setup()
{
System.Console.WriteLine ("Setup");
}
}
sealed class Final : Derived
{
static Final()
{
System.Console.WriteLine ("Final");
}
}
中的那个被执行。
以下是示例源代码:
Final.Setup()
这对我来说只是部分有意义。我理解调用Derived.Setup()
实际上只是Final
的别名,因此跳过Base
中的静态构造函数似乎已经足够了。但是,为什么不调用Base
的静态构造函数?
我可以通过调用Base
的无操作静态方法或访问{{1}}的虚拟静态方法来解决这个问题。但我想知道:这种看似奇怪的行为背后的原因是什么?
答案 0 :(得分:5)
在(根据TCPL):
时调用静态构造函数作为一个例子,考虑一个带有静态 请注意,即使在执行静态构造函数之前,任何静态字段都会初始化为其默认值,然后会为这些字段执行静态字段初始值设定项。只有这样,才会执行静态构造函数(cctor)。 更直接地回答你的问题:静态构造函数不是继承的,也不能直接调用它们,因此你的 关于推理,这很简单,认为C#(在Java中这是不同的):静态方法不会被继承,因此静态构造函数既不应该被继承,因为这可能会导致不必要的副作用(当没有引用该类时调用一个cctor) Main
方法的类,其中执行开始:如果你有一个静态构造函数,那么在调用Main方法之前它将被称为。 / p>
Base
cctor不会在你的场景中调用,除非你给出抽象的Base
类一个静态方法,首先调用它,就像在Base.Initialize()
中一样,就像你已经建议的那样。
答案 1 :(得分:1)
静态方法属于该类,没有继承。您可以调用Final.Setup
的事实只是调用Derived.Setup的语法糖,因此没有引用Final的静态成员 - 因此不会调用静态构造函数。
基类相同 - 静态成员没有继承,因此这里不涉及Base类。
答案 2 :(得分:0)
C#规则规定在创建类的第一个实例之前调用静态构造函数,或者触摸任何静态成员,ergo,可能永远不会,就像你的情况一样。