6

我有三个班级BaseDerivedFinalDerived源自BaseFinal源自Derived。所有三个类都有一个静态构造函数。类Derived作为一个名为Setup. 当我调用 时Final.Setup,我希望所有三个静态构造函数都被执行,但只有一个 inDerived被运行。

这是示例源代码:

    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. 但我想知道:这种明显奇怪的行为背后的原因是什么?

4

3 回答 3

5

在以下情况下调用静态构造函数(根据TCPL):

  • 类类型的一个实例被创建。
  • 类类型的任何静态成员都被引用。

例如,考虑一个具有静态Main方法的类,在该类中开始执行:如果您有一个静态构造函数,它将在调用Main 方法之前调用。

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


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

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

于 2011-06-28T08:31:22.823 回答
1

静态方法属于类,没有继承。您可以调用的事实Final.Setup只是调用 Derived.Setup 的语法糖,因此没有引用 Final 的静态成员 - 因此不调用静态构造函数。Base 类也一样 - 静态成员没有继承,因此 Base 类在这里不涉及任何方式。

于 2011-06-28T08:30:31.093 回答
0

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

于 2011-06-28T08:27:09.010 回答