我有两个类,Foo和Bar,它们都有这样的构造函数:
class Foo
{
Foo()
{
// do some stuff
}
Foo(int arg)
{
// do some other stuff
}
}
class Bar : Foo
{
Bar() : base()
{
// some third thing
}
}
现在我想介绍一个带有int的Bar的构造函数,但是我希望Bar()中发生的事情和一样运行作为来自Foo(int)的东西。像这样:
Bar(int arg) : Bar(), base(arg)
{
// some fourth thing
}
有没有办法在C#中这样做?到目前为止,我所做的最好的事情是将Bar()完成的工作放入一个函数中,也可以通过Bar(int)调用,但这非常不优雅。
答案 0 :(得分:32)
我会重新链接构造函数,因此它们被称为
Bar() : this(0)
Bar(int) : Foo(int) initializes Bar
Foo(int) initializes Foo
Foo() : this(0)
如果无参数构造函数为其他构造函数的int参数假定某种默认值,这是合适的。如果构造函数不相关,你可能会对你的类型做错了,或者我们需要更多关于你想要实现的内容的信息。
答案 1 :(得分:24)
不,这是不可能的。如果使用Reflector检查为每个构造函数生成的IL,您将看到原因 - 您最终会调用基类的两个构造函数。从理论上讲,编译器可以构造隐藏的方法来实现你想要的东西,但是你明确地做同样的事情没有任何优势。
答案 2 :(得分: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
}
}
任何Bar对象的创建现在都将调用所有4个构造函数。构造函数链接应该为更具体的构造函数提供默认值,而不是相反。你应该真正看看你想要完成什么,并确保你所做的事情是有道理的。 Curt是对的,有技术原因你不能这样做,但也有合理的理由你不应该这样做。
答案 3 :(得分:3)
这是我唯一能想到的......
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
}
}
答案 4 :(得分:1)
你不能让Bar构造函数接受一个int调用无参数构造函数吗?
答案 5 :(得分:1)
你能把Bar()中的东西放在Bar(int)中,用Bar()调用Bar(int)的默认值吗?然后Bar(int)可以调用基础构造函数。
class Bar : Foo
{
Bar() : this(0)
{
}
Bar(int arg) : base(arg)
{
}
}
这并不能完全回答您的问题,但根据您的情况,这可能是一个可行的解决方案。
答案 6 :(得分:1)
你可以为Bar()获取初始化代码并使其成为一个方法并从两个构造函数中调用它,并让新的构造函数只调用base(arg)吗?
答案 7 :(得分:0)
您可以使用此代码:
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()
。
希望这很有用。