How to declare constructors in base classes so that sub-classes can use them without declaring them?

6.2k views Asked by At

I want a subclass to use its parent's constructors. But it seems I always need to define them again in the subclass in order for that to work, like so:

public SubClass(int x, int y) : base (x, y) {
    //no code here
}

So I'm wondering if I'm not declaring the constructor properly in the parent class, or is there no direct constructor inheritance at all?

4

There are 4 answers

0
Oded On BEST ANSWER

You are not doing anything wrong.

In C#, instance constructors do not get inherited, so declaring them on the inheriting type and chaining to the base constructor is the right way about it.

From the spec §1.6.7.1:

Unlike other members, instance constructors are not inherited, and a class has no instance constructors other than those actually declared in the class. If no instance constructor is supplied for a class, then an empty one with no parameters is automatically provided.

0
Darin Dimitrov On

So I'm wondering if I'm not declaring the constructor properly in the parent class, because this seems silly.

If the base class doesn't have a default constructor you must redeclare it in the child class. That's how OOP work in .NET.

0
Novakov On

Constructors aren't inherited from base class to derived. Each constructor must call base class ctor first. Compiler knows only how to call parameterless ctor. If there is not such ctor in base class, you have to call it manually.

0
Douglas On

I know this doesn’t directly answer your question; however, if most of your constructors simply introduce a new parameter on the previous constructor, then you could take advantage of optional arguments (introduced in C# 4) to reduce the number of constructors you need to define.

For example:

public class BaseClass
{
    private int x;
    private int y;

    public BaseClass()
        : this(0, 0)
    { }

    public BaseClass(int x)
        : this(x, 0)
    { }

    public BaseClass(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
}

public class DerivedClass : BaseClass
{
    public DerivedClass()
        : base()
    { }

    public DerivedClass(int x)
        : base(x)
    { }

    public DerivedClass(int x, int y)
        : base(x, y)
    { }
}

The above can be reduced to:

public class BaseClass
{
    private int x;
    private int y;

    public BaseClass(int x = 0, int y = 0)
    {
        this.x = x;
        this.y = y;
    }
}

public class DerivedClass : BaseClass
{
    public DerivedClass(int x = 0, int y = 0)
        : base(x, y)
    { }
}

And it would still allow you to initialize both BaseClass and DerivedClass with any number of arguments:

var d1 = new DerivedClass();
var d2 = new DerivedClass(42);
var d3 = new DerivedClass(42, 43);