加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 强制派生类来实现带有参数的基类构造函数

发布时间:2020-12-15 04:06:27 所属栏目:百科 来源:网络整理
导读:是否可以在需要实现构造函数(带参数)的派生类上执行编译时合约? 我有一个基类与构造函数需要一个参数: public class FooBase{ protected int value; public FooBase(int value) { this.value = value; } public virtual void DoSomething() { throw new No
是否可以在需要实现构造函数(带参数)的派生类上执行编译时合约?

我有一个基类与构造函数需要一个参数:

public class FooBase
{
  protected int value;
  public FooBase(int value) { this.value = value; }
  public virtual void DoSomething() { throw new NotImplementedException(); }
}

我想强制派生我的基类实现相同的构造函数:

public class Foo : FooBase
{
  public Foo(int value) : base(value) { }
  public override void DoSomething() { Console.WriteLine("Foo: {0}",value); }
}

如果没有实现构造函数,派生类将导致编译器错误,因为基类中没有默认构造函数:

// ERROR: 'Does not contain a constructor that takes 0 arguments'
// Adding default constructor in FooBase eliminates this compiler error,but
// provides a means to instantiate the class without initializing the int value.
public class FooBar : FooBase
{
  public override void DoSomething() { Console.WriteLine("FooBar: {0}",value); }
}

在派生类中添加默认构造函数FooBar()会使编译器错误静默,但提供了一种实例化FooBar的危险方法,而不需要初始化所需的基类int值.因为我正在使用工厂(见下文),所以沉默编译器错误只会导致运行时错误.我想强制FooBar来实现FooBar(int)

兴趣观察:

如果一个默认构造函数FooBase()被添加到FooBase中,那么它不会由不提供构造函数的派生类继承:

> Foo不会继承默认构造函数,因为它提供了一个显式的构造函数.
> FooBar DOES继承FooBase().

然而,非默??认构造函数FooBase(int)也是如此!

> Foo必须明确地实现FooBase(int)并调用base(int).
> FooBar FAILS以“继承”非默认构造函数的方式与继承默认构造函数的方式相同!

我不想要基类中的默认构造函数,因为实例是使用提供所需“设置”参数的工厂方法创建的.这里没有说明这种工厂方法(使用Activator.CreateInstance()方法).

这是派生类应该被实例化的方式:

static void Main(string[] args)
  {
    FooBase myFoo = new Foo(4);     // Works,since Foo(int) is implemented.

    // ERROR: 'Does not contain a constructor that takes 1 arguments'
    FooBase myFooBar = new FooBar(9);  // Fails to compile.
  }

因为我正在使用工厂 – 不是直接实例化,如图所示 – 没有编译错误.相反,我得到一个运行时异常:“未找到类型的构造方法”.

不可行的解决方案

>接口不支持构造函数.
>构造函数不能是虚拟的或抽象的.

似乎提供基类不能强制执行构造函数的合同.

解决方法:

>在基类中提供默认构造函数以及属性来传递设置参数.

解决方法

If a default constructor,FooBase(),
is added to FooBase,then it is
‘inherited’ by derived classes that do
not provide a constructor:

这是不正确的 – 构造函数通常不会继承.为不提供任何其他构造函数实现的类自动提供默认构造函数.

您可以在为您提供一个Init()方法的接口上加入约束:

public interface IInit
{
   void Init(int someValue);
}

public class FooBase : IInit
{
   ..
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读