LA.NET [EN]

Jul 12

[Update: updated the text that explains why you’d need to make an explicit call to the base class’ constructor. Thanks Damien]

In the last post, I’ve mentioned constructors…but what is a constructor? The first thing you should keep in  mind is that there are several types of constructors and, in this post, we’ll only be talking about instance constructors. So, what’s an instance constructor?

Constructors are special methods which are responsible for initializing an object to a “good” state (curiosity snippet: constructors are represented by .ctor methods in the method definition table of a type). In practice, you create a constructor by adding a method with the same name as the class that does not return anything. Here’s a quick example:

public class Test {
    public Test(){
    }
}

The previous snippet creates an instance constructor which doesn’t receive any parameters. When you don’t define *any* constructor, the C# compiler will automatically add a parameterless (aka, default) constructor which looks like the one shown in the previous snippet.

When you create a new reference type, the runtime ensures that all the fields of that type are zeroed out before the instance constructor gets called. Since constructors are never inherited, then you cannot use the virtual, new, etc. qualifiers with them.  What you should do is call the base class from within your class’s constructor. The following snippet shows how:

public class Test {
    public Test(): base(){
    }
}

Once again,if you don’t add the call explicitly,the compiler will try to add one for you. However, if you’ve introduced a non-parameterless constructor in your base and don’t there’s not any parameterless constructor, then you do need to call the base explicitly (the compiler will remind you of that because it won’t compile your code in these cases):

public class Test {
    public Test(String name){
    }
}
public class Derived:Test {
        public Derived(String name): base(name){
        }
    }
}

Since all types inherit from Object, then you must be probably wondering what happens when the Object’s constructor is called (and it will be called since Object does introduce a default constructor which will be called from within Test’s “customized” constructor). I’m sorry to disappoint you, but the truth is that that constructor simply doesn’t do anything. Yep, that is true…it does nothing, zero, nickles, rien de rien…And the reason for that is really simple: the Object class doesn’t have any state (ie, it defines no fields), so its constructor doesn’t really do anything “visible”.

Even though constructors aren’t inherited, you can still introduce several constructors (overloads) provided they have different signatures. In these cases, you tend to reuse the more specific constructor. Here’s an example of what I mean:

public class Test {
    public Test(String name){
    }
    public Test():this(""){
    }
}

As you can see, the parameterless constructor ends up “redirecting” to the other constructor. Doing this sort of thing is really a good practice because you can centralize all your code in one place.

Before ending this post, there’s still time for talking about initialization. C# allows us to set the initial value of a field in the declaration instruction:

public class Test {
    private Int32 _number = 10;
    public Test(){
    }
}

This is just convenient syntax. During compilation, the compiler will automatically put the initialization for _number in the first line of the default constructor. Do notice that this line is inserted before the call to the base class’ constructor and it will be “replicated” through each of the constructors defined by your class (which might not really be a good thing). In practice, this means that if you have a lot of constructor overloads, you shouldn’t use the field initialization syntax: instead, you should rely on putting the initialization code on a “central” constructor which ends up being called by all the others constructors.

And I guess this covers most of the things you can do with reference type instance constructors. Stay tuned for more.

1 comment so far

  1. Damien
    7:38 am - 7-14-2010

    Just a little niggle:

    However, if you’ve introduced a non-parameterless constructor in your base, then you do need to call the base explicitly

    I think you need to reword that. If your base has *only* parameterised constructors, then you need an explicit call. If you base has *both* parameterised and parameterless constructors, you do not need an explicit call (the compiler will insert a call to the parameterless constructor)