Почему я не могу создать абстрактный конструктор на абстрактном классе С#?

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

public abstract class A
{
    abstract A(int a, int b);
}

Однако я получаю сообщение о том, что абстрактный модификатор недействителен для этого элемента. Моя цель состояла в том, чтобы принудительно создать такой код.

public class B : A
{
    public B(int a, int b) : base(a, b)
    {
        //Some other awesome code.
    }
}

Это все код С#.NET. Может ли кто-нибудь помочь мне?

Обновление 1

Я хотел добавить некоторые вещи. То, что я закончил, было этим.

private A() { }

protected A(int a, int b)
{
    //Code
}

Это то, что говорят некоторые люди, по умолчанию является приватным, а классу необходимо реализовать конструктор. Однако это не FORCE конструктор с сигнатурой A (int a, int b).

public abstract class A
{
    protected abstract A(int a, int b)
    {


    }
}

Обновление 2

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

Ответ 1

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

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

Вообще говоря, единственный способ в С# принудительно использовать определенную подпись конструктора - это использовать ограничение new(), которое обеспечивает существование безпараметрического конструктора для параметра типа.

Ответ 2

Измените этот конструктор в классе A на

protected A(int a, int b)
{
    // Some initialisation code here
}

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

Однако они могут изменить фактическую подпись конструктора. Насколько я знаю, нет способа заставить подкласс использовать конкретную подпись для своего конструктора. Я уверен, что конструкторы не могут быть абстрактными.

Для чего вам это нужно? Мы могли бы предложить работу для этого.

Ответ 3

Хотя вы не можете переопределять конструкторы и поэтому не можете определить абстрактный конструктор, вы можете поместить абстрактный абстрактный метод factory в ваш абстрактный базовый класс. Все производные классы должны были бы переопределить это.

public abstract class A 
{ 
    abstract A MakeAInstance(int a, int b); 
} 

public class B : A 
{ 
    // Must implement:
    override A MakeAInstance(int a, int b) {
        // Awesome way to create a B instance goes here
    }
} 

Ответ 4

Несколько причин:

1) Конструкторы не наследуются, поэтому вы не можете их переопределить.

2) Конструктор - это статическая функция-член, так как для этого не требуется конкретный экземпляр. Абстрактный означает "виртуальный", что означает, что реализация может варьироваться в зависимости от того, как конкретный экземпляр подклассифицирован, что противоположно намерению значения "статического" ключевого слова.

Ответ 5

Вы не можете применять подпись конструктора, так как каждый производный класс может (должен!) определять свой собственный конструктор (ы), и они могут принимать любые параметры, которые им нравятся.

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

Ответ 6

надеюсь, что это поможет кому-то newb, поскольку я я хотел сделать "обычный" публичный класс с ctor, который принимает аргумент, а затем мне нужно было сделать его дочерним классом, поэтому мне понадобился пустой ctor для него.

Я не знал этого раньше: если вы создаете защищенный ctor, тогда класс child видит его, но остальная часть программы не видит его (я думаю, что моя путаница с тех пор в asp.net я вижу все защищенные на странице aspx который наследуется от cs...)

Ответ 7

Все подклассы всегда могут указывать свой собственный конструктор до тех пор, пока они вызывают конструктор суперкласса, поэтому нет способа заставить класс иметь определенный конструктор (по крайней мере, так он работает в Java), Вы можете увидеть, что использование шаблона factory приведет вас куда-нибудь - вы можете определить метод factory в интерфейсе, но вам понадобится отдельный класс factory, так как ваш абстрактный базовый класс не знает фактического класса объект, который необходимо создать.

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

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

Ответ 8

не уверен, что это помогает - но я считаю, что это будет решением вашей проблемы:

public class A
{
  public A(int a, int b)
  {
    DoSomething(int a, int b);
  }

  virtual public void DoSomething(int a, int b)
  {

  }
}

public class B : A
{
  override public void DoSomething(int a, int b)
  {
    //class specific stuff
  }
}

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