在派生类中自动使基础构造函数可用?

Mic*_*tum 20 .net c# inheritance

我有一个带有两个构造函数的Base类,需要一个参数:

public abstract class StoreBase 
{
    private readonly SomeObject_sobj;

    protected StoreBase(SomeObject sobj)
    {
        _sobj = sobj;
    }

    protected StoreBase(OtherObject oobj)
    {
        _sobj = new SomeObject(oobj);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我有一个派生类:

public class MyDerived: StoreBase
{

}
Run Code Online (Sandbox Code Playgroud)

这会导致编译错误base class doesn't contain parameterless constructor.

我的理解是,因为MyDerived不包含构造函数,所以编译器添加了一个无参数构造函数(这是众所周知的,与派生类无关).但是,因为它派生自另一个类,所以基类构造函数需要先运行,并且无法确定应从空MyDerived构造函数运行哪个构造函数.

基本上我问:如果我真的不需要额外的构造函数逻辑,我可以避免将所有构造函数从Base复制/粘贴到Derived类中吗?我可以说"从基地拿走所有施工人员"而不加全部吗?

(是的,我知道我可以/应该将它重构为无参数构造函数和受保护的虚拟Initialize()方法.但我仍然想知道我是否可以使用构造函数并仍然避免复制/粘贴)

Ree*_*sey 15

否 - 您还需要在派生类中实现(适当的)构造函数.

派生类只需要使用其中一个基本构造函数 - 因此其中所需的构造函数可能与基类完全不同.它们需要手工实施,即使只是:

public class MyDerived : StoreBase
{
     public MyDerived(SomeObject sobj) : base(sobj) {}
     public MyDerived(OtherObject  oobj) : base(oobj) {}
}
Run Code Online (Sandbox Code Playgroud)

也:

(是的,我知道我可以/应该将它重构为无参数构造函数和受保护的虚拟Initialize()方法.但我仍然想知道我是否可以使用构造函数并仍然避免复制/粘贴)

虽然我看到这个被吹捧,但我相信这并不总是一个好习惯.在许多情况下,这实际上是有问题的,因为如果它们覆盖受保护的虚拟方法,则依赖于子类来正确调用Initialize.例如,如果子类执行此操作,则可能非常糟糕:

public class MyDerived : StoreBase
{
   // .. other stuff
   protected override void Initialize()
   {
       // Leave out, intentionally or accidentally, the following:
       // base.Initialize(); 
   }
}
Run Code Online (Sandbox Code Playgroud)

我实际上在大多数情况下避免这种情况,并在构造函数中初始化(或在私有的非虚拟初始化方法中).不执行此操作会破坏您的初始化将始终按照您的意图发生的任何保证.

构造函数和构造函数链提供相同的功能,并提供更好的保证.