Могу ли я наследовать конструкторы?

Я знаю, что невозможно наследовать конструкторы в C #, но, вероятно, есть способ сделать то, что я хочу.

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

public Constructor(Parameter p) {
    base.Init(p);
}

Это полностью нарушает принципы СУХОГО! Как я могу инициализировать все необходимые вещи без создания десятков конструкторов?

 Slipp D. Thompson24 сент. 2014 г., 22:00
C # in действительно не следует за DRY вообще. Это может быть неприятно, но ... честно, вы не можете сказать мне, что вы не устали печататьpublic, protected, а такжеprivate снова и снова и снова?
 Jon Hanna06 окт. 2010 г., 16:29
Хуже, чем нарушение принципов СУХОЙ, является нарушение принципа инварианта.Init поскольку имя метода обычно является сильным признаком того, что объекты без необходимости существуют в недопустимых состояниях, где единственное, для чего они хороши, это вызывает ошибки.
 Mark K Cowan21 дек. 2016 г., 14:45
@ SlippD.Thompson: это еще одна область, где C ++ на самом делеМеньше словесные, а не простые языки ... Предыдущий, который я только что видел, касался раскрытия базовых конструкторов в производном классе.

Ответы на вопрос(5)

Что-то вроде этого?

public Constructor(Parameter p) : base(p) {

}

И базовый класс:

public Base(Parameter p)
{
    Init(p);
}

Вы даже можете пометить свойInit метод как виртуальный, так что вы можете сделать некоторые сладкие переопределения в других ваших классах, если это будет необходимо! ;)

public virtual void Init() { }

и в других ваших классах:

public override void Init() { base.Init(); //Do other stuff }
 AHM06 окт. 2010 г., 19:14
Виртуальный метод инициализации кажется бессмысленным. Обычно вам следует избегать выполнения работы в конструкторах и использовать их только для инициализации, и если это только инициализация, то почему бы просто не использовать конструктор?
 Arcturus06 окт. 2010 г., 16:22
правда :) но вы найдете этот вопрос очень быстро ..
 thecoop06 окт. 2010 г., 16:14
Хотя вы должны быть очень осторожны при вызове виртуального метода из конструктора - конструктор подкласса не запустится, когда переопределенный метод будет вызван суперклассом, поэтому переменные-члены и т. Д. Не были бы инициализированы.

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

class A
{
    protected A(int x)
    {

    }
}
class B : A
{
    B(int x)
        : base(x)
    {

    }
}

Единственный способ не повторятьbase.Init вызов должен вместо этого вызвать базовый конструктор

class Base
{
  public Base(Parameter p)
  {
    this.Init(p)
  }

  private void Init(Parameter p)
  {
      ...
  }
}

class Inherited : Base
{
   public Inherited(Parameter p)
     : base(p)
   {
      // other constructor logic, but Init is already called.
   }
}
Решение Вопроса

все с одним и тем же кодом; вы создаете только один, но производные классы вызывают базовый конструктор:

public class Base
{
    public Base(Parameter p)
    {
        Init(p)
    }

    Init(Parameter p)
    {
        // common initialisation code
    }
}

public class Derived : Base
{
    public Derived(Parameter p) : base(p)
    {

    }
}
 Ion Todirel19 мая 2016 г., 12:33
Хотелось бы, чтобы у C # было что-то вроде наследующих конструкторов C ++, но все равно раздражает вызывать все базовые конструкторы
 Rob Levine27 авг. 2014 г., 14:45
почему отрицательный голос?
 Damien Sawyer23 февр. 2019 г., 22:16
Постоянное двойное обращение с конструкторами довольно раздражает ... так что я начал гуглить почему. Прочитав обсуждение здесь, я чувствую себя менее расстроенным по этому поводу. Есть несколько веских причин, по которым они этого не сделали.social.msdn.microsoft.com/forums/en-US/...
 Alex06 окт. 2010 г., 16:20
Это то что мне нужно. Хотя мне придется создавать конструкторы для классов, у которых их нет, мне не придется повторять код.

а затем вызовите его из унаследованных объектов следующим образом:

public InheritedObject(Parameter p) : base(p)
{
}

Базовый конструктор будет вызван до запуска любого кода в самом конструкторе.

Ваш ответ на вопрос