在C#中调用重写的构造函数和基础构造函数

我有两个类,富和酒吧,有这样的构造:

class Foo { Foo() { // do some stuff } Foo(int arg) { // do some other stuff } } class Bar : Foo { Bar() : base() { // some third thing } } 

现在我想介绍一个Bar的构造函数,它需要一个int,但是我想要Bar()中发生的东西以及Foo(int)中的东西运行。 像这样的东西:

 Bar(int arg) : Bar(), base(arg) { // some fourth thing } 

有没有办法在C#中做到这一点? 到目前为止,我所做的最好的工作是将Bar()完成的工作放到一个函数中,这个函数也被Bar(int)调用,但是这样很不雅观。

不,这是不可能的。 如果你使用Reflector来检查为每个构造函数生成的IL,你会看到为什么 – 你最终会调用这两个基类的构造函数。 理论上,编译器可以构build隐藏的方法来实现你想要的东西,但是明确地做同样的事情确实没有任何优势。

我会重新链接构造函数,所以他们被称为像

 Bar() : this(0) Bar(int) : Foo(int) initializes Bar Foo(int) initializes Foo Foo() : this(0) 

如果无参数的构造函数为其他构造函数的int参数假设某种默认值,这是合适的。 如果构造函数不相关,那么你的types可能做错了,或者我们需要更多关于你想要实现的东西的信息。

我会build议改变你的构造链从最不具体到最具体的。

 class Foo { Foo() { // do some stuff } Foo(int arg): this() { // do some other stuff } } class Bar : Foo { Bar() : Bar(0) { // some third thing } Bar(int arg): base(arg) { // something } } 

Bar对象的任何创build都将调用所有4个构造函数。 构造函数链应该为更具体的构造函数提供默认值,而不是相反。 你真的应该看看你正在努力完成什么,并确保你在做什么是有道理的。 Curt是正确的,有技术上的原因,你不能这样做,但也有逻辑的原因,你为什么不应该这样做。

这只是我能想到的

  public class Foo { public Foo() { } public Foo(int? arg): this() { } } public class Bar : Foo { private int x; public Bar(): this(new int?()) // edited to fix type ambiguity { // stuff that only runs for paramerless ctor } public Bar(int? arg) : base(arg) { if (arg.HasValue) { // Do stuff for both parameterless and parameterized ctor } // Do other stuff for only parameterized ctor } } 

你不能有酒吧的构造函数接受一个int调用无参数的构造函数?

你可以把Bar()中的东西放在Bar(int)中,并用Bar()调用Bar(int)的默认值? 然后Bar(int)可以调用基础构造函数。

 class Bar : Foo { Bar() : this(0) { } Bar(int arg) : base(arg) { } } 

这并不完全回答你的问题,但取决于你的情况可能是一个可行的解决scheme。

你可以把Bar()的初始化代码作为一个方法,并从两个构造函数中调用它,并让新的构造函数调用base(arg)?

你可以使用这个代码:

 public Foo { public Foo() { this.InitializeObject(); } public Foo(int arg) : this() { // do something with Foo's arg } protected virtual void InitializeObject() { // initialize object Foo } } public Bar : Foo { public Bar : base() { } public Bar(int arg) : base(arg) { // do something with Bar's arg } protected override void InitializeObject() { // initialize object Bar base.InitializeObject(); } } 

就像在上面的代码中重写InitializeObject()方法,并把你想要放在无参数构造函数中的所有代码放在那里。 最后在代码的最后调用base.InitializeObject()

希望这是有用的。