Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 自动使基构造函数在派生类中可用?_C#_.net_Inheritance - Fatal编程技术网

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

C# 自动使基构造函数在派生类中可用?,c#,.net,inheritance,C#,.net,Inheritance,我有一个带有两个构造函数的基类,需要一个参数: public abstract class StoreBase { private readonly SomeObject_sobj; protected StoreBase(SomeObject sobj) { _sobj = sobj; } protected StoreBase(OtherObject oobj) { _sobj = new SomeObje

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

public abstract class StoreBase 
{
    private readonly SomeObject_sobj;

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

    protected StoreBase(OtherObject oobj)
    {
        _sobj = new SomeObject(oobj);
    }
}
然后我有一个派生类:

public class MyDerived: StoreBase
{

}
这会导致编译错误,因为
基类不包含无参数构造函数

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

基本上我是在问:如果我真的不需要额外的构造函数逻辑,我能避免将所有构造函数从基类复制/粘贴到派生类中吗?我可以说“从基中获取所有构造函数”而不添加它们吗

(是的,我知道我可以/应该把它重构成一个无参数构造函数和一个受保护的virtualinitialize()方法。但是我仍然想知道我是否可以使用构造函数并避免复制/粘贴)

我可以说“从基中获取所有构造函数”而不添加它们吗


否:-(

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

派生类只需要使用一个基类构造函数-因此它所需的构造函数可能与基类完全不同。它们需要手动实现,即使只是:

public class MyDerived : StoreBase
{
     public MyDerived(SomeObject sobj) : base(sobj) {}
     public MyDerived(OtherObject  oobj) : base(oobj) {}
}

此外:

(是的,我知道我可以/应该把它重构成一个无参数构造函数和一个受保护的virtualinitialize()方法。但是我仍然想知道我是否可以使用构造函数并避免复制/粘贴)

虽然我看到这一点被吹捧,但我相信这并不总是一个好的做法。在许多情况下,这实际上是有问题的,因为如果子类覆盖了受保护的虚拟方法,则依赖子类来正确调用Initialize。例如,如果子类这样做,可能会非常糟糕:

public class MyDerived : StoreBase
{
   // .. other stuff
   protected override void Initialize()
   {
       // Leave out, intentionally or accidentally, the following:
       // base.Initialize(); 
   }
}
实际上,我在大多数情况下都会避免这种情况,并在构造函数中进行初始化(或在私有的非虚拟初始化方法中进行初始化)。不这样做会破坏您的任何保证,即您的初始化将始终按照您所希望的方式进行


构造函数和构造函数链接提供了相同的功能,有更好的保证。

不幸的是,答案是否定的

您可以做的一件事是从MyDevered构造函数调用base:

class MyDerived: StoreBase
{
public MyDerived(OtherObject obj) : base (obj) {}
}

不,构造函数不是继承的,并且没有创建基本构造函数副本的快捷方式

最接近的是实现调用基构造函数的构造函数。我想您还是想公开它们,这样您就可以实际创建类的实例:

public MyDerived(SomeObject sobj) : base(sobj) {}
public MyDerived(OtherObject oobj) : base(oobj) {}

如果您自己没有提供任何构造函数,编译器将只生成默认(无参数)构造函数。定义构造函数后,编译器将不会为您生成构造函数

如果您计划序列化类,请务必记住这一点,因为序列化需要一个默认构造函数。如果您为类指定的构造函数不是默认构造函数,那么您也需要提供一个默认构造函数来支持序列化,因为一旦您提供了任何构造函数,编译器将不会自动为您提供