6

As I know Constructors of parent class is called first and then child Class.But why In Case of static Constructor It executes from derived Class first and then Child Class?

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Child t = new Child();
        }
    }
    
    class Parent
    {
        public Parent()
        {
            Console.WriteLine("Parent Instance Constructor");
            Console.ReadKey();
        }
        static Parent()
        {
            Console.WriteLine("Parent Static Constructor");
            Console.ReadKey();
        }
    }
    class Child : Parent
    {
        public Child()
        {
            Console.WriteLine("Child Instance Constructor");
            Console.ReadKey();
        }

        static Child()
        {
            Console.WriteLine("Child Static Constructor");
            Console.ReadKey();
        }
    }
}

Output:

Child Static Constructor

Parent Static Constructor

Parent Instance Constructor

Child Instance Constructor

Now As per Jeppe Stig Nielsen Suggestion when i have intialised static fields in constructors,it is running in following order

Output

Parent Static Constructor

Child Static Constructor

Parent Instance Constructor

Child Instance Constructor

class XyzParent
{
    protected static int FieldOne;
    protected int FieldTwo;

    static XyzParent()
    {
        // !  
        FieldOne = 1;
        Console.WriteLine("parent static");
    }
    internal XyzParent()
    {
        // !  
        FieldOne = 10;
        // !  
        FieldTwo = 20;
        Console.WriteLine("parent instance");
    }
}

class XyzChild : XyzParent
{
    static XyzChild()
    {
        // !  
        FieldOne = 100;
        Console.WriteLine("child static");
    }
    internal XyzChild()
    {
        // !  
        FieldOne = 1000;
        // !  
        FieldTwo = 2000;
        Console.WriteLine("child instance");
    }
}

Why such contradictory behaviour?

Steve Friedl
  • 3,929
  • 1
  • 23
  • 30
F11
  • 3,703
  • 12
  • 49
  • 83
  • 2
    It would be more interesting if you gave the class `Parent` two fields, one `static` one and one instance field. Then the constructors should assign to the fields. Static constructors can only assign to the static fields, but instance constructors can assign to both fields. Will the constructors run in the same order then? – Jeppe Stig Nielsen Mar 17 '13 at 15:01
  • It will help you understand if you put in more Console.WriteLines in there. I'll update your code to show you where. Put in Console.WriteLines where I added `// !`, read my answer, run your code again, and see if you now understand what is going on here. There is no contradiction. – Eric Lippert Mar 17 '13 at 20:21
  • Related: [In what order are the static constructors of parent and child classes called?](http://stackoverflow.com/questions/5240011/) – Jeppe Stig Nielsen Mar 17 '13 at 20:44

3 Answers3

24

First off, the behaviour is not contradictory at all; it is all consistent with the rules. You just don't know what the rules are.

You should read all of my two-part series on instance constructors and my four-part series on the semantics of static constructors. They start here:

http://blogs.msdn.com/b/ericlippert/archive/2008/02/15/why-do-initializers-run-in-the-opposite-order-as-constructors-part-one.aspx

and here:

http://ericlippert.com/2013/02/06/static-constructors-part-one/

respectively.

Those should clearly answer your question, but in case it is not 100% clear let me sum up. The relevant rules are:

  • Rule One: A static constructor runs before any static field is accessed, before any static method is executed, and before any instance constructor is executed.
  • Rule Two: A derived-class instance constructor calls the base class instance constructor before it runs the derived class instance constructor body.

So what happens when you execute new Child()?

  • Rule One applies. We are about to call the instance constructor of Child, so we must first call the static constructor of Child. So it runs first.
  • After the static constructor of Child returns, the instance constructor of Child runs. Rule Two applies: the first thing the Child instance constructor does before it runs its body is runs the instance constructor of Parent.
  • Rule One applies again. We are about to call the instance contructor of Parent, so we must first call the static constructor of Parent. So it runs.
  • After the static constructor of Parent returns, the instance constructor of Parent runs. Rule Two applies: it invokes the instance constructor of object, which does nothing interesting, and then runs the body of the instance constructor of Parent.
  • Control returns to the instance constructor of Child, and its body runs.

So there you go; the order is the Child static constructor, then the Parent static constructor, then the Parent body, then the Child body.

Now let's look at your second example. What happens when you say new XyzChild?

  • Rule One applies. We are about to call the instance constructor of XyzChild, so we first call the static constructor of XyzChild. It's body starts executing, and...
  • ...Rule One applies again. We are about to access a static field of XyzParent, so XyzParent's static constructor must execute.
  • XyzParent's static constructor executes. It accesses a field, but the static constructor is already in flight on this thread, so it does not recursively trigger the static constructor again. It prints out that it is in the parent.
  • Control returns to the child's static constructor, which prints out that it is in the child.
  • Now the child's instance constructor can run. Rule Two applies: XyzParent's instance constructor runs first.
  • Rule One applies, but the static constructor for XyzParent has already run, so it is skipped.
  • The body of XyzParent's instance constructor executes and returns control to XyzChild's static constructor.
  • The body of XyzChild's instance constructor runs.

So there you go. There's no inconsistency whatsoever; the two rules are applied correctly.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • Ah, of course. So in the last case, the initial part of `XyzChild`'s static constructor runs first, then the execution of the constructor is kind of "suspended" while the entire static constructor of `XyzParent` is run, and only then is control returned to the static constructor of `XyzChild` whose remaining portion is run. – Jeppe Stig Nielsen Mar 17 '13 at 21:03
  • 1
    @JeppeStigNielsen: It is "suspended" in exactly the same way that *every* method is "suspended" when you call another method; a return address and new activation frame is pushed on the stack, the new method is called, and when it returns, the activation frame is popped and the original method resumes at the return address. There's no magic, except insofar as the call site of the method you're calling does not appear in source code. – Eric Lippert Mar 17 '13 at 21:11
6

Static Constructors are always executed before the non-static constructor. Static constructor is called when class is accessed first time.

From MSDN Doc,

  • A static constructor does not take access modifiers or have parameters.
  • 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.
  • A typical use of static constructors is when the class is using a log file and the constructor is used to write entries to this file.
  • Static constructors are also useful when creating wrapper classes for unmanaged code, when the constructor can call the LoadLibrary method.
  • If a static constructor throws an exception, the runtime will not invoke it a second time, and the type will remain uninitialized for the lifetime of the application domain in which your program is running.
John Woo
  • 258,903
  • 69
  • 498
  • 492
  • 1
    but why static constructor of Child Class is executed first unlike instance constructor? – F11 Mar 17 '13 at 15:03
  • see bullet no. 2: `A static constructor is called automatically to initialize the class before the first instance is created or any static members are referenced.`, `Child` is created first. `Parent` Class is not created but only inherited. – John Woo Mar 17 '13 at 15:05
  • 1
    But the order in which the two `static` constructors are called is not well-defined with the above code, in my opinion. If, however, the static constructors of both classes access some static field of the `Parent` class, then the static constructors will run in a definite order, I believe, and that is not the order the Original Poster gets. – Jeppe Stig Nielsen Mar 17 '13 at 15:16
  • @JeppeStigNielsen what do you mean by *"..are called is not well-defined with the above code."*? `Parent` class is not created, it is only inherited. `Child` class is created that's why it outputs `Child Static Constructor`, but before it will call the child's non-static constructor, it will initialize the inherited class first and in this case, the `Parent` class. – John Woo Mar 17 '13 at 15:21
  • I don't know. The runtime could say: "Alright, I predict that at some point in the near future I will need to run `Parent` static constructor, so let me do this first. Now, certainly, I also have to run `Child` static constructor, and I feel it's a good time to do it now. Then, the code says `Child t = new Child();`, now I'm allowed to run that part (instance constructors)." If it did that, I think it would be allowed. _The user has no control on when the static constructor is executed in the program_ (quote from your quote). See also my answer where the situation is a little different. – Jeppe Stig Nielsen Mar 17 '13 at 15:31
  • @JeppeStigNielsen: The order in which static constructors are executed is well-defined in both pieces of code given. See my answer for details. It only becomes implementation-defined when there are static fields with initializers and *no* static ctor. (Or when order dependency is based on field lexical order and there is no lexical order because the fields are in two halves of a partial class.) – Eric Lippert Mar 17 '13 at 20:19
2

The order in which the static constructors are run is undefined (I think) in your case. The only thing that is guaranteed, is that they will run before instances are created.

I changed you code into:

    class XyzParent
    {
        protected static int FieldOne;
        protected int FieldTwo;

        static XyzParent()
        {
            FieldOne = 1;
            Console.WriteLine("parent static");
        }
        internal XyzParent()
        {
            FieldOne = 10;
            FieldTwo = 20;
            Console.WriteLine("parent instance");
        }
    }
    class XyzChild : XyzParent
    {
        static XyzChild()
        {
            FieldOne = 100;
            Console.WriteLine("child static");
        }
        internal XyzChild()
        {
            FieldOne = 1000;
            FieldTwo = 2000;
            Console.WriteLine("child instance");
        }
    }

Now it matters more which order they run in, for they write to the same field. And with my version of the code, saying new XyzChild(); leads to this output:

parent static
child static
parent instance
child instance

EDIT: Eric Lippert's answer gives a more precise explanation. The above code only does WriteLine at the end of the static constructors. Add additional WriteLine at the beginning of the static constructors to see that the XyzParent static constructor is run "in the middle" of the execution of the XyzChild static constructor.

Jeppe Stig Nielsen
  • 60,409
  • 11
  • 110
  • 181
  • ,but why such behbaviour?I am not able to understand?Can you explain? – F11 Mar 17 '13 at 15:40
  • 1
    @little Have you tried reading the section _Static constructors_ in the _C# Language Specification_? On my computer it's located in the `'C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC#\Specifications\1033'` folder (the numbers may be a bit different with you depending on versions and locale). After reading it, I'm not so sure I was right in saying the order is undefined. It's more a matter of whether the `static` constructor of `Child` references members from `Parent` or not. If it doesn't (like in your example) it can run first. If it does (my example), the `Parent` cctor runs first. – Jeppe Stig Nielsen Mar 17 '13 at 16:27
  • 1
    The order in which the static constructors run is well-defined in both programs. – Eric Lippert Mar 17 '13 at 20:30