我需要从一个构造函数的主体调用另一个构造函数。我该怎么做呢?
基本上class foo {
public foo (int x, int y)
{
}
public foo (string s)
{
// ... do something
// Call another constructor
this (x, y); // Doesn't work
foo (x, y); // neither
}
}
你不能。
你必须找到一种方法来链接这些构造函数,如:
public foo (int x, int y) { }
public foo (string s) : this(XFromString(s), YFromString(s)) { ... }
或将构造代码移动到公共设置方法中,如下所示:
public foo (int x, int y) { Setup(x, y); }
public foo (string s)
{
// do stuff
int x = XFromString(s);
int y = YFromString(s);
Setup(x, y);
}
public void Setup(int x, int y) { ... }
this(x, y)
是正确的,但它必须在构造函数主体开始之前:
public Foo(int x, int y)
{
...
}
public Foo(string s) : this(5, 10)
{
}
注意:
- 你只能链接到一个构造函数,
this
或base
-构造函数可以链接到另一个,当然。 - 构造函数体在链式构造函数调用之后执行。没有办法先执行构造函数体。
- 你不能在其他构造函数的参数中使用
this
,包括调用实例方法-但是你可以调用静态方法。 - 任何实例变量初始化器在链式调用之前执行。
在我的文章中有关于构造函数链的更多信息
要显式调用base和this类构造函数,您需要使用下面给出的语法(注意,在c#中您不能像c++那样使用它来初始化字段):
class foo
{
public foo (int x, int y)
{
}
public foo (string s) : this(5, 6)
{
// ... do something
}
}
//编辑:注意,你在你的样本中使用了x,y。当然,以这种方式调用ctor时给出的值不能依赖于其他构造函数的参数,它们必须以其他方式解析(它们不需要是常量,尽管在上面编辑的代码示例中)。如果x
和y
是从s
计算出来的,你可以这样做:
这是不支持的-参见c#中的构造函数。
然而,你可以实现一个公共的(私有的)方法,从不同的构造函数调用…
我自己也遇到过一两次这样的问题。最后,我不得不将另一个构造函数中需要的任何逻辑提取到private void
方法中,并在两个地方调用它。
class foo
{
private void Initialize(int x, int y)
{
//... do stuff
}
public foo(int x, int y)
{
Initialize(x, y);
}
public foo(string s_
{
// ... do stuff
Initialize(x, y)
// ... more stuff
}
}
MSDN中MethodBase.Invoke
的描述中有一个注释
如果使用此方法重载来调用实例构造函数,则为obj提供的对象被重新初始化;也就是说,所有实例初始化函数被执行。返回值为空。如果一个类构造函数被调用时,类被重新初始化;这就是所有的阶级初始化函数被执行。返回值为空
。您可以通过反射获得构造函数的方法,并通过Invoke
在新的构造函数体中调用它。但是我还没有试过。当然,这个解决方案也有很多缺点。