Автоматически делающие Основные Конструкторы, доступные в производном классе?

У меня есть Базовый класс с двумя конструкторами, требуя параметра:

public abstract class StoreBase 
{
    private readonly SomeObject_sobj;

    protected StoreBase(SomeObject sobj)
    {
        _sobj = sobj;
    }

    protected StoreBase(OtherObject oobj)
    {
        _sobj = new SomeObject(oobj);
    }
}

Тогда у меня есть производный класс:

public class MyDerived: StoreBase
{

}

Это вызывает ошибку компиляции как base class doesn't contain parameterless constructor.

Мое понимание - то, что, потому что MyDerived не содержит конструктора, компилятор добавляет конструктора без параметров (это известно и ничто, чтобы сделать с производными классами). Однако, поскольку это происходит из другого класса, конструктор базового класса должен работать сначала, и нет никакого способа определить, какой конструктор должен работать от пустого конструктора MyDerived.

В основном я спрашиваю: я могу избежать, копируют/вставляют всех конструкторов с Основы в Производный класс, если мне действительно не нужна дополнительная логика конструктора? Я могу сказать, "Берут всех конструкторов от основы", не добавляя их всех?

(И да, я знаю, что мог осуществить рефакторинг, это в конструктора без параметров и защищенное виртуальное Инициализирует () метод. но я все еще задаюсь вопросом, могу ли я работать с конструкторами и все еще избежать скопировать/вставить),

20
задан Joel Coehoorn 19 January 2010 в 18:18
поделиться

5 ответов

Нет - вам нужно будет реализовать (соответствующие) конструкторы в полученном классе.

Полученный класс должен использовать только один из базовых конструкторов - поэтому конструкторы, необходимые в нем, могут быть совершенно отличными, чем базовый класс. Им нужно будет реализовать вручную, даже если это только:

public class MyDerived : StoreBase
{
     public MyDerived(SomeObject sobj) : base(sobj) {}
     public MyDerived(OtherObject  oobj) : base(oobj) {}
}

также:

(и да, я знаю, что могу / должен рефакторировать это в конструктор без параметра и защищенным виртуальным методом инициализации (). Но я все еще Интересно, могу ли я работать с конструкторами и по-прежнему избегать копирования / вставки)

Хотя я вижу это рекламировал, я считаю, что это не всегда хорошая практика. Во многих случаях это на самом деле проблематично, так как вы полагаетесь на подкласс, чтобы правильно вызова инициализировать, если они переопределяют ваш защищенный виртуальный метод. Например, если подкласс сделал это, он потенциально может быть очень плохо:

public class MyDerived : StoreBase
{
   // .. other stuff
   protected override void Initialize()
   {
       // Leave out, intentionally or accidentally, the following:
       // base.Initialize(); 
   }
}

Я фактически избегаю этого в большинстве ситуаций, и инициализируюсь в конструкторах (или в частном, не виртуальном методе инициализации). Не делать это ломает любые гарантии, у вас есть, что ваша инициализация всегда будет происходить так, как вы намереваетесь.

Конструкторы и цепочка конструктора обеспечивают ту же функциональность, с гораздо лучшим гарантом.

15
ответ дан 30 November 2019 в 00:59
поделиться

Нет, конструкторы не наследуются, и нет ярлыка для создания копий базовых конструкторов.

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

public MyDerived(SomeObject sobj) : base(sobj) {}
public MyDerived(OtherObject oobj) : base(oobj) {}
3
ответ дан 30 November 2019 в 00:59
поделиться

Могу ли я сказать «Возьми все конструкторы из базы», ​​не добавляя их всех?

нет. : - (

1
ответ дан 30 November 2019 в 00:59
поделиться

Компилятор будет генерировать только конструктор по умолчанию (PARMEMERLALLE), если вы не предоставили самого конструктора. Как только вы определяете конструктор, компилятор не будет генерировать для вас.

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

3
ответ дан 30 November 2019 в 00:59
поделиться

К сожалению, ответ нет.

Одна вещь, которую вы можете сделать, это призвать базу из своего моюдированного конструктора:

class MyDerived: StoreBase
{
public MyDerived(OtherObject obj) : base (obj) {}
}
2
ответ дан 30 November 2019 в 00:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: