简体   繁体   中英

Wondering why Static Constructor is not hit in derived class and base class

This is a little sample I was helping myself for understanding constructors working with many scenarios. I am surprised why static constructors in this scene is not being hit at all.

I am well aware about the Static constructors and even have experienced how they work. I know that, first the static constructor in the derived class gets hit and then the one in base class and then any other constructors. But I don't know why in this particular case where I "ENFORCE" base class parameterized constructor to work, is this the reason the static constructors are not getting hit ? This is what I could suspect/understand, however I may be wrong. But I cannot agree with this, if this is going to be the reason.

Here s the code I worked in VS 2010 now:

    public class MyBaseClass
    {
        public MyBaseClass(int x)
        {
        }
        static MyBaseClass()
        {
        }
    }

    public class MyDerivedClass : MyBaseClass
    {
        public MyDerivedClass(int i)
            : base(5)
        {
        }
        public MyDerivedClass() : base(2)
        {
        }
        static MyDerivedClass()
        {
        }
        public static void Main()
        {
            new MyDerivedClass();
        }
    }

I can't see why series0ne's answer is -ve marked. It's a detailed explanation of how constructors work, with examples.

However, one thing I like to point out is that static constructors of base and derived will be called in addition to default/specific constructors by simply doing 'new B()' as the only statement. You don't need to declare a variable of type A (or B for that matter) and assign to it to ensure static constructor of base is invoked. (Contradicting comment - series0ne Aug 17 '12 at 14:09)

Following is the an example (I wrote to verify) and its outcome:

class A
{
    static A()
    {
        Console.WriteLine("Static A.");
    }

    public A()
    {
        Console.WriteLine("Non-Static A.");
    }
}

class B : A
{
    static B()
    {
        Console.WriteLine("Static B.");
    }

    public B()
    {
        Console.WriteLine("Non-Static B.");
    }
}

void Main()
{
    new B();
}

Static B.
Static A.
Non-Static A.
Non-Static B.

EDIT - Inconsistent and incomplete testing led to an incorrect answer on my part, and with the interest of clear, concise and CORRECT answers, this post has been entirely updated.

The difference between static and non-static constructors:

A static constructor is called automatically before the first use of an object. It's purpose is to set up any static fields/properties/objects(etc.) of itself before any instantiation of itself occurs. Therefore if I define class A to have a static constructor, and create an instance of A, the static constructor will execute before A is instantiated.

Let's say for example that I construct two instances of A, I only see the static constructor for A once...why!? Because static construction only needs to occur once for a particular object type. Beyond that, there is no point in performing static constructions because its already been done!

Consider the following code for this exercise:

    public class A
    {
        static A()
        {
            Console.WriteLine("Hello from static A");
        }

        public A()
        {
            Console.WriteLine("Hello from non-static A");
        }
    }

    public class B : A
    {
        static B()
        {
            Console.WriteLine("Hello from static B");
        }

        public B() : base() //explicit so you know B() will call A()
        {
            Console.WriteLine("Hello from non-static B");
        }
    }

Consider the following instantiation of A and it's results:

class Program
{
    static void Main(string[] args)
    {
        A instance_1 = new A();

        Console.Read();
    }
}

Results: Hello from static A, Hello from non-static A

Since A is instantiated once in this instance, static A is called, then non-static A

Consider the following instantiation of A (x2) and it's results:

class Program
{
    static void Main(string[] args)
    {
        A instance_1 = new A();
        A instance_2 = new A();

        Console.Read();
    }
}

Results: Hello from static A, Hello from non-static A, Hello from non-static A

As A is instantiated twice, static A is called once (as static A is a one-time operation) and non-static A is called twice to create two instances of A

Consider the following instantiation of B assigned to from A and it's results:

    class Program
    {
        static void Main(string[] args)
        {
            A instance_1 = new B();

            Console.Read();
        }
    }

Results: Hello from static B, Hello from static A, Hello from non-static A, Hello from non-static B

Now both A and B are being statically constructed (first time only) because B is a descendant of A. This is evident as well in that non-static B calls non-static A. as A is the ancestor or B

Finally consider this example...

class Program
{
    static void Main(string[] args)
    {
        A instance_1 = new B();
        B instance_2 = new B();

        Console.Read();
    }
}

Results: Hello from static B, Hello from static A, Hello from non-static A, Hello from non-static B, Hello from non-static A, Hello from non-static B

Again, A and B are statically constructed (one time only) but non-static A and non-static B repeat as their are now two instances of B, therefore the non-static construction occurs for every new instance of the object

It might be worth also taking note that it appears that static construction and non-static construction calls in inheritance work the opposite way round to each other. IE in the last example, static B is called before static A, however non-static A is called before non-static B!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM