Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why isn't the static constructor from my base class called? [duplicate]

Lets say I have 2 classes:

public abstract class Foo
{
    static Foo()
    {
        print("4");
    }
}

public class Bar : Foo
{
    static Bar()
    {
        print("2");
    }

    static void DoSomething()
    {
        /*...*/
    }
}

I expected that after calling Bar.DoSomething() (assuming this is the first time I access the Bar class) the order of event will be:

  1. Foo's static constructor (again, assuming first access) > print 4
  2. Bar's static constructor > print 2
  3. Execution of DoSomething

At the bottom line I expect 42 to be printed.
After testing, it seems that only 2 is being printed.
And that is not even an answer.

Can you explain this behavior?

like image 636
Avi Turner Avatar asked Nov 20 '13 09:11

Avi Turner


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.

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.

Does base class constructor get called automatically?

Whenever the derived class's default constructor is called, the base class's default constructor is called automatically. To call the parameterized constructor of base class inside the parameterized constructor of sub class, we have to mention it explicitly.

Why static constructor is Parameterless in C#?

A static constructor must be parameterless because nothing ever calls it, it is invoked when you access a static member or create an instance of the class, but not directly (it is called by the runtime).


2 Answers

The specification states:

The static constructor for a class executes at most once in a given application domain. The execution of a static constructor is triggered by the first of the following events to occur within an application domain:

  1. An instance of the class is created.
  2. Any of the static members of the class are referenced.

Because you are not referencing any of the members of the base class, the constructor is not being excecuted.

Try this:

public abstract class Foo
{
    static Foo()
    {
        Console.Write("4");
    }

    protected internal static void Baz()
    {
        // I don't do anything but am called in inherited classes' 
        // constructors to call the Foo constructor
    }
}

public class Bar : Foo
{
    static Bar()
    {
        Foo.Baz();
        Console.Write("2");
    }

    public static void DoSomething()
    {
        /*...*/
    }
}

For more information:

  • C# in Depth - Jon Skeet: C# and beforefieldinit
  • StackOverflow: What's the best way to ensure a base class's static constructor is called?
like image 136
dav_i Avatar answered Nov 09 '22 00:11

dav_i


The reason base class static constructor is not called is because, we are not yet accessing any static members of the base class nor creating the instance of the derived class.

As per documentation these are the times when a static constructor will be called.

It is called automatically before the first instance is created or any static members are referenced.

In the below code when we invoke DoSomething the base class constructor will be called

public abstract class Foo
{
    static Foo()
    {
        Console.Write("4");
        j = 5;
    }

    protected static int j;

    public static void DoNothing()
    {

    }
}

public class Bar : Foo
{
    static Bar()
    {
        Console.Write("2");
    }

    public static void DoSomething()
    {
        Console.Write(j);
    }
}
like image 27
Ramesh Avatar answered Nov 09 '22 00:11

Ramesh