views:

400

answers:

6

I have few types that derive from simplified Base as shown below.

I am not sure whether to use base class's constructor or this constructor when overloading constructors.

ConcreteA overloads constructors purely using base constructors, while
ConcreteB overloads using this for the first two overloads.

What would be a better way of overloading constructors?

public abstract class Base
{
    public string Name { get; set; }
    public int? Age { get; set; }

    protected Base() : this(string.Empty) {}
    protected Base(string name) : this(name, null) {}
    protected Base(string name, int? age)
    {
        Name = name;
        Age = age;
    }
}

public class ConcreteA : Base
{
    public ConcreteA(){}
    public ConcreteA(string name) : base(name) {}
    public ConcreteA(string name, int? age) : base(name, age)
    {
    }
}

public class ConcreteB : Base
{
    public ConcreteB() : this(string.Empty, null){}
    public ConcreteB(string name): this(name, null){}
    public ConcreteB(string name, int? age) : base(name, age)
    {
    }
}

[Edit] It looks like what Ian Quigley has suggested in his answer seemed to make sense. If I were to have a call that initialize validators, ConcreteA(string) will never initialize validators in following case.

public class ConcreteA : Base
{
    public ConcreteA(){}
    public ConcreteA(string name) : base(name) {}
    public ConcreteA(string name, int? age) : base(name, age)
    {
        InitializeValidators();
    }
    private void InitializeValidators() {}
}
+1  A: 

In your case from what you have provided it doesn't matter. You really only want to use this when you have a constructor in your current class that is not part of your base class, or if there is some code in the current class constructor that you want to execute that isn't contained in the base class.

Nick Berardi
+4  A: 

This. Because if you ever place code in ConcreteB(string, int?) then you want the string only constructor to call it.

Dead account
This seems to make sense if I were to have other initializations going on in concrete constructors.
Sung Meister
Yes, and "this" will always call "base" at the end of the day. So even if "this" does nothing, it'll drop down to "base"
Dead account
+2  A: 

In general, I'd call "this" rather than "base". You'll probably reuse more code that way, if you expand your classes later on.

dommer
A: 

In order to reduce the complexity of the code paths, I usually try to have exactly one base() constructor call (the ConcreteB case). This way you know that the initialization of the base class always happens in the same fashion.

However, depending on the class you override, this may not be possible or add unneeded complexity. This holds true for special constructor patterns such as the one when implementing ISerializable.

Lucero
+2  A: 

It is fine to mix and match; ultimately, when you use a this(...) constructor, it will eventually get to a ctor that calls base(...) first. It makes sense to re-use logic where required.

You could arrange it so that all the constructors called a common (maybe private) this(...) constructor that is the only one that calls down to the base(...) - but that depends on whether a: it is useful to do so, and b: whether there is a single base(...) ctor that would let you.

Marc Gravell
A: 

Ask yourself again why you are overloading the constructor in the Base class? This one is enough:

protected Base()

Same goes for the subclass unless you need either fields to have a particular value when you instantiate which in your example is not the case since you already have the default constructor.

Also remember that any constructor should put the instance of the object in a correct state.

moin