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



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



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.
}
}


Это все C# .NET код. Кто-нибудь может мне помочь вышел?



обновление 1



Я хотел добавить некоторые вещи. В итоге я получил вот что.



private A() { }

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


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



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


}
}


обновление 2



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

880   8  

8 ответов:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Comments

    Ничего не найдено.