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

rei*_*lly 50 c# constructor

我有两个类,Foo和Bar,它们有这样的构造函数:

class Foo
{
    Foo()
    {
      // do some stuff
    }

    Foo(int arg)
    {
      // do some other stuff
    }
}

class Bar : Foo
{
    Bar() : base()
    {
      // some third thing
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我想介绍一个带有int的构造函数,但是我想要在Bar()中运行的东西以及来自Foo(int)的东西.像这样的东西:

Bar(int arg) : Bar(), base(arg)
{
  // some fourth thing
}
Run Code Online (Sandbox Code Playgroud)

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

Ily*_*kov 32

我会重新链接构造函数,因此它们被称为

Bar() : this(0) 
Bar(int) : Foo(int) initializes Bar
Foo(int) initializes Foo
Foo() : this(0) 
Run Code Online (Sandbox Code Playgroud)

如果无参数构造函数为其他构造函数的int参数假定某种默认值,这是合适的.如果构造函数不相关,那么您可能会对类型做错,或者我们需要更多关于您要实现的内容的信息.


Cur*_*her 24

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


Ner*_*ury 13

我建议您更改构造函数链,从最不具体到最具体.

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
    }
}
Run Code Online (Sandbox Code Playgroud)

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