Как объявить конструкторы в базовых классах, чтобы подклассы могли использовать их, не объявляя их?

Я хочу, чтобы подкласс использовал конструкторы своего родителя. Но, кажется, мне всегда нужно определять их снова в подклассе, чтобы это работало, вот так:

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

Поэтому мне интересно, правильно ли я объявляю конструктор в родительском классе, или нет прямого наследования конструктора вообще?

4 ответа

Решение

Вы не делаете ничего плохого.

В C# конструкторы экземпляров не наследуются, поэтому их правильное объявление в виде наследуемого типа и связывание с базовым конструктором.

Из спецификации §1.6.7.1:

В отличие от других членов, конструкторы экземпляров не наследуются, и у класса нет конструкторов экземпляров, кроме тех, которые фактически объявлены в классе. Если конструктор экземпляра не предоставлен для класса, то автоматически предоставляется пустой конструктор без параметров.

Я знаю, что это не дает прямого ответа на ваш вопрос; однако, если большинство ваших конструкторов просто вводят новый параметр в предыдущем конструкторе, вы можете воспользоваться дополнительными аргументами (введенными в C# 4), чтобы уменьшить количество конструкторов, которые вы должны определить.

Например:

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)
    { }
}

Выше может быть уменьшено до:

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)
    { }
}

И это все равно позволит вам инициализировать оба BaseClass а также DerivedClass с любым количеством аргументов:

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

Конструкторы не наследуются от базового класса до производного. Каждый конструктор должен сначала вызвать базовый класс ctor. Компилятор знает только, как вызвать ctor без параметров. Если в базовом классе нет такого ctor, вы должны вызвать его вручную.

Поэтому мне интересно, не правильно ли я объявляю конструктор в родительском классе, потому что это кажется глупым.

Если базовый класс не имеет конструктора по умолчанию, вы должны переопределить его в дочернем классе. Вот как ООП работает в.NET.

Другие вопросы по тегам