为什么不在C#中调用所有静态构造函数(即父类的那些)?

时间:2011-06-28 08:21:58

标签: c# static-constructor

我有三个课程,BaseDerivedFinalDerived Base来自FinalDerived来自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}}的虚拟静态方法来解决这个问题。但我想知道:这种看似奇怪的行为背后的原因是什么?

3 个答案:

答案 0 :(得分:5)

在(根据TCPL):

时调用静态构造函数
  • 创建了类类型的实例。
  • 引用类类型的任何静态成员。

作为一个例子,考虑一个带有静态Main方法的类,其中执行开始:如果你有一个静态构造函数,那么在调用Main方法之前它将被称为。 / p>

请注意,即使在执行静态构造函数之前,任何静态字段都会初始化为其默认值,然后会为这些字段执行静态字段初始值设定项。只有这样,才会执行静态构造函数(cctor)。


更直接地回答你的问题:静态构造函数不是继承的,也不能直接调用它们,因此你的Base cctor不会在你的场景中调用,除非你给出抽象的Base类一个静态方法,首先调用它,就像在Base.Initialize()中一样,就像你已经建议的那样。

关于推理,这很简单,认为C#(在Java中这是不同的):静态方法不会被继承,因此静态构造函数既不应该被继承,因为这可能会导致不必要的副作用(当没有引用该类时调用一个cctor)

答案 1 :(得分:1)

静态方法属于该类,没有继承。您可以调用Final.Setup的事实只是调用Derived.Setup的语法糖,因此没有引用Final的静态成员 - 因此不会调用静态构造函数。 基类相同 - 静态成员没有继承,因此这里不涉及Base类。

答案 2 :(得分:0)

C#规则规定在创建类的第一个实例之前调用静态构造函数,或者触摸任何静态成员,ergo,可能永远不会,就像你的情况一样。