是否可以在需要实现构造函数(带参数)的派生类上执行编译时合约?
我有一个基类与构造函数需要一个参数:
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. }
因为我正在使用工厂 – 不是直接实例化,如图所示 – 没有编译错误.相反,我得到一个运行时异常:“未找到类型的构造方法”.
不可行的解决方案
似乎提供基类不能强制执行构造函数的合同.
解决方法: