Why aren't all static constructors called in C# (i.e. those of the parent classes)?

六眼飞鱼酱① 提交于 2020-01-01 09:57:09

问题


I have three classes, Base, Derived and Final. Derived derives from Base and Final derives from Derived. All three classes have a static constructor. Class Derived as a public static method called Setup. When I call Final.Setup, I expect that all three static constructors get executed, but only the one in Derived gets run.

Here is the sample source code:

    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");
        }
    }

This makes only partially sense to me. I understand that calling Final.Setup() is in fact just an alias for Derived.Setup(), so skipping the static constructor in Final seems fair enough. However, why isn't the static constructor of Base called?

I can fix this by calling into a no-operation static method of Base or by accessing some dummy static method of Base. But I was wondering: what is the reasoning behind this apparently strange behavior?


回答1:


A static constructor is called when (according to TCPL):

  • An instance of the class type is created.
  • Any of the static members of the class type are referenced.

As an example, consider a class with the static Main method in which execution begins: if you have a static constructor, it will be called before the Main method is called.

Note that even before a static constructor is executed, any static fields are initialized to their default value and then the static field initializers are executed for those field. Only then, the static constructor (cctor) is executed.


To answer your question more directly: static constructors are not inherited, and they cannot be called directly, hence your Base cctor will not be called in your scenario, unless you give the abstract Base class a static method and call that first, i.e. as in Base.Initialize(), as you already suggested.

About the reasoning, that's simple, thinking C# (in Java this is different): static methods are not inherited, thus static constructors should neither be inherited as this could cause unwanted side effects (a cctor called when nothing references that class).




回答2:


Static methods belong to the class and there is no inheritance. The fact that you can call Final.Setup is just a syntactic sugar for calling Derived.Setup, so no static member of Final has been referenced - therefore the static constructor is not called. Same for Base class - there is no inheritance on static members, so the Base class is not involved in any way here.




回答3:


The C# rules dictate that static constructors are called before the first instance of the class is created or any static member is touched, ergo, possibly never, as in your case.



来源:https://stackoverflow.com/questions/6503588/why-arent-all-static-constructors-called-in-c-sharp-i-e-those-of-the-parent-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!