C# constructor execution order
Asked Answered
M

7

165

In C#, when you do

Class(Type param1, Type param2) : base(param1) 

is the constructor of the class executed first, and then the superclass constructor is called or does it call the base constructor first?

Machismo answered 10/12, 2009 at 17:40 Comment(1)
in C# language specAnticlinal
L
210

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.

Laetitia answered 10/12, 2009 at 17:53 Comment(9)
It seems like half of my contributions here are pointing to his answers; but Eric Lippert wrote a good pair of posts on this topic as well: blogs.msdn.com/ericlippert/archive/2008/02/15/… blogs.msdn.com/ericlippert/archive/2008/02/18/…Ophelia
Including the effects of collection initializers, a bit more in depth than the question perhaps, but a good read.Ophelia
+1 for the comparison with Java. Also, I think that's the case for C++ but I'm not 100% sure.Benjaminbenji
FYI, in vb.net, derived-class field initializers run after base-class initialization is complete (which is IMHO how things should be). Among other things, this means that derived-class fields can be initialized using fields or properties of the object under construction.Highroad
@supercat: On the other hand, it means you can't call any members in the base class, because that part hasn't been initialized yet...Laetitia
@Jon Skeet: In vb.net, you can call base-class members from derived-class initializers. Derived-class methods virtual-called from base-class constructor cannot rely upon their field initializers to have run, but I would consider designs that rely upon derived-class field initializers to run before the base constructor to be somewhat brittle anyway, since they would not be adaptable to any scenario where the initialization values would depend upon construction parameters.Highroad
@supercat: Okay, I think I'd misread your previous comment. I thought you meant the actual constructor body executes before the base class constructor, which would be odd indeed. It sounds like the VB way is basically akin to the Java approach.Laetitia
@Jon Skeet: No, I meant that everything to do with the base executes before the derived class. Actually, what I'd most prefer would be a declaration to allow four modes for fields: (1) initialize before base constructor; (2) initialize after base constructor, and allow use of base members in computation; (3) initialize from constructor parameter of same name/format (every constructor would have to have parameters of those names and types or chain to one which did), or (4) act as an "ephemeral" field, initialized as #3, but only accessible from other initializers.Highroad
@Jon Skeet: [so if sizeLimit was an int parameter pseudo-field, and a field declaration read 'var bar=new int[sizeLimit];', all constructors with foo as their parameter could perform bar=new int[sizeLimit], even before calling the base constructor, which is something that's presently not possible].Highroad
S
68

It will call the base constructor first. Also keep in mind that if you don't put the :base(param1) after your constructor, the base's empty constructor will be called.

Stendhal answered 10/12, 2009 at 17:43 Comment(0)
D
22

Not sure if this should be a comment/answer but for those who learn by example this fiddle illustrates the order as well: https://dotnetfiddle.net/kETPKP

using System;

// order is approximately
/*
   1) most derived initializers first.
   2) most base constructors first (or top-level in constructor-stack first.)
*/
public class Program
{
    public static void Main()
    {
        var d = new D();
    }
}

public class A
{
    public readonly C ac = new C("A");

    public A()
    {
        Console.WriteLine("A");
    }
    public A(string x) : this()
    {
        Console.WriteLine("A got " + x);
    }
}

public class B : A
{
    public readonly C bc = new C("B");

    public B(): base()
    {
        Console.WriteLine("B");
    }
    public B(string x): base(x)
    {
        Console.WriteLine("B got " + x);
    }
}

public class D : B
{
    public readonly C dc = new C("D");

    public D(): this("ha")
    {
        Console.WriteLine("D");
    }
    public D(string x) : base(x)
    {
        Console.WriteLine("D got " + x);
    }
}

public class C
{
    public C(string caller)
    {
        Console.WriteLine(caller + "'s C.");
    }
}

Result:

D's C.
B's C.
A's C.
A
A got ha
B got ha
D got ha
D
Dandiprat answered 16/8, 2016 at 20:5 Comment(0)
P
21

The constructor of the baseclass is called first.

Pettis answered 10/12, 2009 at 17:43 Comment(1)
better don't decompile the new (c#12) primary constructors on normal non-record classesAmpliate
O
2

[Edit: in the time it took me to answer, the question had totally changed].

The answer is that it calls the base first.

[Original answer to the old question below]

Are you asking when you would do the "base" bit of the constructor call?

If so, you would "chain" a call to the constructor base if the class is derived from another class which has this constructor:

  public class CollisionBase
    {
        public CollisionBase(Body body, GameObject entity)
        {

        }
    }

    public class TerrainCollision : CollisionBase
    {
        public TerrainCollision(Body body, GameObject entity)
            : base(body, entity)
        {

        }
    }

In this example, TerrainCollision derives from CollisionBase. By chaining the constructors in this way, it ensures the specified constructor is called on the base class with the supplied parameters, rather than the default constructor (if there is one on the base)

Occam answered 10/12, 2009 at 17:45 Comment(0)
G
1

Your question is a bit unclear but I'm assuming you meant to ask the following

When to I call the base constructor for my XNA object vs. using the impilict default constructor

The answer to this is highly dependent on both your scenario and the underlying object. Could you clarify a bit wit the following

  • What is the scenario
  • What is the type of the base object of TerrainCollision?

My best answer though is that in the case where you have parameters that line up with the parameters of the base class`s constructor, you should almost certainly be calling it.

Grissel answered 10/12, 2009 at 17:44 Comment(0)
S
0

Constructor mechanism is much better as it leaves the application to use constructor chaining and if you were to extend the application it enables through inheritance the ability to make minimal code changes. Jon Skeets Article

Shorthorn answered 20/7, 2015 at 12:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.