C# Constructor Execution Order

C# constructor execution order

The order is:

  • Member variables are initialized to default values for all classes in the hierarchy

Then starting with the most derived class:

  • Variable initializers are executed for the most-derived type
  • Constructor chaining works out which base class constructor is going to be called
  • The base class is initialized (recurse all of this :)
  • The constructor bodies in the chain in this class are executed (note that there can be more than one if they're chained with Foo() : this(...) etc

Note that in Java, the base class is initialized before variable initializers are run. If you ever port any code, this is an important difference to know about :)

I have a page with more details if you're interested.

Order of calling constructors case of inheritance in c#

A base class Constructor is called first.Refer to the following example

// Demonstrate when constructors are called.
using System;

// Create a base class.
class A {
public A() {
Console.WriteLine("Constructing A.");
}
}

// Create a class derived from A.
class B : A {
public B() {
Console.WriteLine("Constructing B.");
}
}

// Create a class derived from B.
class C : B {
public C() {
Console.WriteLine("Constructing C.");
}
}

class OrderOfConstruction {
static void Main() {
C c = new C();
}
}

The output from this program is shown here:

Constructing A.
Constructing B.
Constructing C.

C# constructor chaining - changing the order of execution

You can't call constructors inside other constructors. A constructor can only chain another constructor to be called directly before it.

However, to solve your particular issue, you can make a private constructor that can accept both a types of argument, and have your two original constructors both simply chain this one, passing null for the missing argument.

This has the advantage over calling private initialisation methods that it plays nicely with readonly fields (i.e. it still works if myThing is a readonly field):

public class Foo
{
private static Dictionary<string, Thing> ThingCache =
new Dictionary<string, Thing>();
private Thing myThing;

public Foo(string name)
: this(null, name)
{
}

public Foo(Thing tmpThing)
: this(tmpThing, null)
{
}

private Foo(Thing tmpThing, string name)
{
if (tmpThing == null && name == null)
{
throw new System.ArgumentException(
"Either tmpThing or name must be non-null.");
}

doSomeStuff();
if (tmpThing != null)
{
myThing = tmpThing;
}
else
{
if (ThingCache.ContainsKey(name))
{
myThing = ThingCache[name];
}
else
{
myThing = ExternalStaticFactory.GetThing(name);
ThingCache.Add(name, myThing);
}
}
doSomeOtherStuff();
}
}

You could also use named or optional arguments if you are using C# 4.0:

http://msdn.microsoft.com/en-us/library/dd264739.aspx

C# base() constructor order

It'll be 2. Constructors run in order from base class first to inherited class last.

Note that initialisers (both static and instance variables) run in the opposite direction.

The full sequence is here: http://www.csharp411.com/c-object-initialization/

Constructor Chaining Order

The chained constructor will be called immediately prior to the body of the defining constructor. The IL sequence generated is an immediate call to the other constructor, followed by the IL generated from the statements in the constructor.

So if you chain to another constructor and that constructor calls InitializeComponent() the calling constructor should not call this method.

For example, given this sample class:

class Foo {
public int A, B;

public Foo() : this(1) {
B = 2;
}

public Foo(int a) {
A = a;
}
}

This is the generated IL:

  .class private auto ansi beforefieldinit Foo
extends [mscorlib]System.Object
{
.field public int32 A
.field public int32 B

// method line 1
.method public hidebysig specialname rtspecialname
instance default void '.ctor' () cil managed
{
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldc.i4.1
IL_0002: call instance void class Foo::'.ctor'(int32)
IL_0007: ldarg.0
IL_0008: ldc.i4.2
IL_0009: stfld int32 Foo::B
IL_000e: ret
} // end of method Foo::.ctor

// method line 2
.method public hidebysig specialname rtspecialname
instance default void '.ctor' (int32 a) cil managed
{
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void object::'.ctor'()
IL_0006: ldarg.0
IL_0007: ldarg.1
IL_0008: stfld int32 Foo::A
IL_000d: ret
} // end of method Foo::.ctor

} // end of class Foo

Note that the no-arg constructor calls the other constructor before assigning 2 to the B field.

Constructor execution order of Java and C# and its real impact on code porting

On the answer you've linked to, Jon Skeet provides a link to "a page with more details", in which he uses this example:

public class MyBaseClass
{
public MyBaseClass ()
{
Console.WriteLine (this.ToString());
}
}

public class MyDerivedClass : MyBaseClass
{
string name="hello";

public MyDerivedClass() : base()
{
Console.WriteLine (this.ToString());
}

public override string ToString()
{
return name;
}
}

When a new instance of MyDerivedClass is created in C#, the output is:

hello
hello

The first line is hello because the instance variable initializer for the name variable has run directly before the base class constructor. The equivalent code in Java syntax would output:

null
hello

I wouldn't consider this example to be particularly contrived: it's not unthinkable that someone would call a virtual method (like ToString()) in a base class, nor that a virtual method would try to use a member variable. In fact, it wouldn't be very far-fetched to assume that this is something Jon might have run into personally, considering he has authored libraries and their ports in both languages.

But, as he mentions:

This is a really bad idea - wherever possible, only call non-virtual methods from constructors, and if you absolutely must call a virtual method, document very carefully that it is called from the constructor, so that people wishing to override it are aware that their object may not be in a consistent state when it is called (as their own constructor won't have run yet).

So anti-pattern: yes. Deliberately designed? Perhaps not.

Order of constructors for a C# class: parameterized, default, and static?

You are right, in terms of the order.

The static constructor runs first, then the non-parameterized constructor, then the parameterized constructor.

The JIT timing should not be an issue. The CLR guarantees that your static constructor will complete prior to any instance being constructed.

However, the assembly resolution is happening BEFORE your static constructor fires. The runtime needs to resolve the assembly (and its dependencies) prior to invoking any static construction. That's why you're running into this problem.

Base constructor in C# - Which gets called first?

The base constructor will be called first.

try it:

public class MyBase
{
public MyBase()
{
Console.WriteLine("MyBase");
}
}

public class MyDerived : MyBase
{
public MyDerived():base()
{
Console.WriteLine("MyDerived");
}
}


Related Topics



Leave a reply



Submit