为什么我不能在抽象的C#类上创build抽象构造函数?

我正在创build一个抽象类。 我希望我的每个派生类都被迫实现特定的构造函数签名。 因此,我做了我想要强迫他们实施的方法,我做了一个抽象的方法。

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#不会让你这样做。

你不能有一个抽象的构造函数,因为抽象意味着你必须在任何非抽象的子类中覆盖它,你不能重载构造函数。

如果你仔细想想,这是有道理的,因为你总是调用子类的构造函数(使用new运算符),而不是基类。

一般来说,C#中强制执行特定构造函数签名的唯一方法是使用new()通用约束,它强制types参数存在无参数构造函数。

将类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)构造函数不是inheritance的,因此你不能覆盖它们。

2)构造函数是一个静态成员函数,因为它不需要调用特定的实例。 抽象意味着“虚拟”,这意味着实现可以根据具体实例如何分类而变化,这与“静态”关键字的含义的意图是相反的。

你不能执行构造函数签名,因为每个派生类可能(必须!)定义它自己的构造函数,并且可能采用他们喜欢的任何参数。

如果您需要将给定的一组variables传递给派生类的对象,则需要定义一个抽象方法,这需要由派生类实现。 如果这个类没有实现这个抽象方法,你会得到一个编译器错误。

希望这将有助于某人newb,因为我正在寻求做一个“正常”的公共课,需要争论的ctor,然后我需要使它成为一个孩子类,所以我需要一个空的ctor。

我以前不知道这一点:如果你做一个受保护的ctor然后孩子类看到它,但程序的其余部分没有看到它(我想我的困惑是因为在asp.net我看到所有保护的aspx页面,从inheritanceCS …)

所有的子类总是可以指定自己的构造函数,只要他们调用超类的构造函数 – 所以没有办法迫使一个类有一个特定的构造函数(至less,这是它在Java中的工作方式)。 你可以看到使用工厂模式会让你在某个地方 – 你可以在接口中定义一个工厂方法 – 但是你需要一个单独的工厂类,因为你的抽象基类不知道需要的对象的实际类创build。

但是:也许增加一个更具体的问题,你可能会提示其他/更好的回应。 你正在寻找一些通用的实例化代码,或者你是否担心抽象基类上的特定设置必须完成?

如果您只关心抽象类必须完成的初始化,请创build一个方法来logging该方法的使用情况。

不知道这是否有帮助 – 但我觉得这将是解决您的问题:

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

结果是你可以用正确的行为在任何派生类中调用一个构造函数。