Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling of Static Constructor and Instance Constructor

Tags:

c#

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?

like image 518
F11 Avatar asked Mar 17 '13 14:03

F11


2 Answers

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.

like image 57
Eric Lippert Avatar answered Sep 29 '22 09:09

Eric Lippert


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

  • Static Constructors

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.
like image 43
John Woo Avatar answered Sep 29 '22 09:09

John Woo