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

Pie*_*aud 6 c# static-constructor

我有三个班Base,DerivedFinal.Derived源自BaseFinal衍生自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");
        }
    }
Run Code Online (Sandbox Code Playgroud)

这对我来说只是部分有意义.我知道调用Final.Setup()实际上只是一个别名Derived.Setup(),所以跳过静态构造函数Final似乎很公平.但是,为什么不Base调用静态构造函数?

我可以通过调用一个无操作的静态方法Base或通过访问一些虚拟静态方法来解决这个问题Base.但我想知道:这种看似奇怪的行为背后的原因是什么?

Abe*_*bel 5

(根据TCPL)调用静态构造函数:

  • 创建类类型的实例.
  • 引用类类型的任何静态成员.

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

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


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

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