我的类中有一个初始化东西的默认构造函数。
我不希望将其复制/粘贴到我需要的:base(otherStuff)
的另一个构造函数中。我猜我必须(或将其抽象出方法或某些东西)。
但我想知道,为什么两者都不受支持?
(有时当我想要语言不支持的东西时,意味着我做错了。)
示例:
public class SomeClass : SomeBase
{
public SomeClass()
{
// Init a lot of lists and stuff
}
public SomeClass(OtherThings otherThings): base(otherThings)
// :this() <----- This is not legal syntax
{
// Do stuff with otherThings
}
}
答案 0 :(得分:3)
我认为这样做的原因是,在执行类型的任何构造函数之前,基本构造函数始终执行,这意味着从现有构造函数{{1}派生你的类型已经嵌入了基础构造者c1()
- 并且你显然不能从2个不同的基础构造中派生出来。
由于b1()
构造函数实际上是从this()
构造函数隐式派生的,所以有点令人困惑,所以你的代码相当于:
base()
现在很明显你不能拥有public class SomeClass : SomeBase
{
public SomeClass(): **base()**
{
// Init a lot of lists and stuff
}
public SomeClass(OtherThings otherThings): base(otherThings)
// :this() <----- This is not legal syntax
{
// Do stuff with otherThings
}
}
,因为编译器无法执行2个基本构造函数(SomeClass(OtherThings otherThings): base(otherThings):this()
和base(otherThings)
)。
<强> UPD:强> 考虑到为什么禁止依赖2个构造函数,我进入了这个例子:
base()
允许public class SomeBase {
public SomeBase(){}
public SomeBase(OtherThings otherThings):this(){}
}
public class SomeClass : SomeBase
{
public SomeClass(): base()
{
// Init a lot of lists and stuff
}
public SomeClass(OtherThings otherThings): base(otherThings)
// :this() <----- This is not legal syntax
{
// Do stuff with otherThings
}
}
会导致SomeClass(OtherThings otherThings):base(otherThings):this()
被执行两次,这是荒谬和意外的(一次为SomeBase()
,另一次为:base(otherThings)
,这两者都依赖于无参数构造函数SomeClass(): base()
)。
答案 1 :(得分:2)
我不确切知道为什么,但我过去有类似的东西,不得不求助于... ...
public class SomeClass : SomeBase
{
public SomeClass()
{
// Init a lot of lists and stuff
CommonStuff();
}
public SomeClass(OtherThings otherThings): base(otherThings)
{
CommonStuff();
// Do stuff with otherThings
}
private void CommonStuff()
{
// init common between both
}
}
答案 2 :(得分:2)
考虑这种情况:
class Base
{
public Base() { }
public Base(string s) { }
}
class Derived : Base
{
public Derived() : base("default") { }
public Derived() : base()
: this() { }
}
应该很清楚,如果允许,这可以保证会造成麻烦。最终会调用哪个基础构造函数?
已经提供了解决方案:将其提取到方法中。
答案 3 :(得分:0)
这背后有一个非常可靠的推理 - 在开始在派生类型中构造构造函数之前,你的基类应该被完全初始化。
从您的示例看,您有两种不同的方法来初始化一个类 - 也许您应该考虑更改您的架构以便更简单?
如果不可能,您可能确实喜欢使用初始化方法或链接构造函数,如:
class A
{
// no longer needed
//public A()
//{
//}
public A(SomeStuff stuff)
{
if (stuff != null)
{
// init stuff
}
}
}
class B : A
{
public B() : this(null)
{
}
public B(SomeStuff stuff) : base(stuff)
{
if (stuff != null)
{
// init stuff more
}
}
}
在这种情况下,您的施工链是正确的 - this.default() -> this.specialized(null) -> base.specialized(null)
。
当然,如果A()
正在执行任何重要操作,您可以保留它,只需从A(SomeStuff)
拨打电话。