【问题标题】:Abstract class with constructor, force inherited class to call it带有构造函数的抽象类,强制继承类调用它
【发布时间】:2019-07-26 16:30:30
【问题描述】:

我有一个带有构造函数 XYZ(string name)abstract 类。
我还有一个继承自该抽象类的类。

如何强制继承类调用base(string name)

现在我可以使用new Inherited(),它不会调用基本构造函数。我想强制用户在继承类中实现默认构造函数。

【问题讨论】:

    标签: c#


    【解决方案1】:

    没有显式构造函数的类有一个无参数构造函数。另一方面,如果你实现了一个带参数的构造器并且没有无参数的构造器,你的类在没有参数的情况下是不能实例化的。

    换句话说:

    public abstract class A 
    {
        public A(string x) 
        {
        }
    }
    
    public class B : A 
    {
        // If you don't add ": base(x)" 
        // your code won't compile, because A has a 
        // constructor with parameters!
        public B(string x) : base(x)
        {
        }
    }
    

    也就是说,如果A 有无参数构造函数(或没有显式构造函数),B 将自动调用基本构造函数。您无需在此处编写任何其他代码。

    否则,如果你的基类有无参构造函数和有参构造函数,则不能强制派生类自动调用除默认构造函数以外的构造函数(即所谓的无参构造函数) em>。

    解决方法

    好吧,这里没有特殊的解决方法,但请注意 C# 在构造函数和方法中都支持可选参数。

    如果您想 100% 确定派生类将调用具体的基构造函数,则可以使用带有可选参数的单个无参数构造函数来实现基类,并使用 this 而不是构造函数重载:

    public class A
    {
        public A(string x = "hello world") // or just string x = null
        {
    
        }
    }
    

    现在如果B 类派生AB 将始终调用A 的基本构造函数,因为x 是可选的并且它具有默认值。

    【讨论】:

    • 我猜你错过了A中的一个参数
    • @SriramSakthivel 谢谢!
    • 工作太累了。在 c# 中有 3 年的经验,但我可以认识到发生了什么。我在抽象类 0_0 的构造函数中有默认参数。该回家了。 ;p
    • @zgnilec 哈哈,好吧,检查我的更新,我给你一个可能的解决方法;)
    【解决方案2】:

    如何强制继承类调用base(string name)

    将抽象类中的无参数构造函数设为私有,或者根本不添加它。这将强制所有派生类调用您指定的构造函数,否则会出现编译错误。

    public abstract class BaseClass
    {
        protected BaseClass(string parameter)
        {
        }
    }
    
    public class DerivedClass : BaseClass
    {
        public DerivedClass()
        {
        }
    }
    

    最终会是

    '`Project.BaseClass`' does not contain a constructor that takes 0 arguments
    

    【讨论】:

      【解决方案3】:

      你不需要做任何事情。所有派生类构造函数必须调用基类构造函数(除了一些particularly evil hacks,您可能不需要担心)。如果代码中没有明确指定,则隐含对基类的无参数构造函数的隐式调用。如果基类没有无参数构造函数(例如添加一个接受字符串的构造函数并且没有显式添加无参数构造函数),则该类将无法编译。

      【讨论】:

        【解决方案4】:

        过去半个小时左右,我再次试验了一个抽象基类的排列,该基类的默认构造函数标记为私有,一个带有 4 个参数的重载,以及一个只有 4 个参数重载的派生类.使用最新的 C# 编译器(7.3),很明显在这种情况下:

        1. 派生类必须显式定义 4 参数重载。
        2. 派生类调用 4 参数重载的重载必须是显式的。

        基类构造函数签名

        public OperatingParameterBase (
            string pstrInternalName ,
            string pstrDisplayName ,
            T penmParameterType ,
            U penmDefaultParameterSource )
        

        派生类构造函数

        internal OperatingParameter (
            string pstrInternalName ,
            string pstrDisplayName ,
            T penmParameterType ,
            U penmDefaultParameterSource )
            : base (
                  pstrInternalName ,
                  pstrDisplayName ,
                  penmParameterType ,
                  penmDefaultParameterSource )
        {
        }   // internal OperatingParameterExample constructor
        

        我在派生类中展示了整个构造函数,以证明调用基类构造函数是它唯一的绝对要求。由于基本构造函数的工作与本次讨论无关,因此我将其省略了。

        【讨论】:

          猜你喜欢
          • 2011-11-17
          • 1970-01-01
          • 1970-01-01
          • 2015-08-06
          • 1970-01-01
          • 1970-01-01
          • 2018-11-29
          • 2015-12-10
          • 2010-11-26
          相关资源
          最近更新 更多