Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 229
Pierre Arnaud Avatar asked Jun 28 '11 08:06

Pierre Arnaud


People also ask

Why static constructor is called only once?

A static constructor is used to initialize any static data, or to perform a particular action that needs to be performed only once. It is called automatically before the first instance is created or any static members are referenced.

Why are constructors always non-static?

A constructor is called when an object of a class is created, so no use of the static constructor. Another thing is that if we will declare static constructor then we can not access/call the constructor from a subclass. Because we know static is allowed within a class but not by a subclass.

How do you call a static constructor?

A static constructor is called automatically to initialize the class before the first instance is created or any static members are referenced. A static constructor cannot be called directly. The user has no control on when the static constructor is executed in the program.

How many static constructors can be declared in a class?

A class or struct can only have one static constructor. Static constructors cannot be inherited or overloaded.


1 Answers

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).

like image 70
Abel Avatar answered Sep 27 '22 02:09

Abel