我有一个通用界面,
public interface ICalculator<in T>
{
void Calculate(T input);
}
通用计算器,
public class GeneralCalculator<T> : ICalculator<T>
{
public void Calculate(T input)
{
bla bla
}
}
仅适用于某些类型的特定计算器,
public class SpecificAndFastCalculator<T> : ICalculator<T> where T : ISpecificInterface
{
public void Calculate(T input)
{
bla bla
}
}
和装饰ICalculators的装饰者:
public class CalculatorDecorator<T> : ICalculator<T>
{
private readonly ICalculator<T> component;
public CalculatorDecorator()
{
component = (typeof (ISpecificInterface).IsAssignableFrom(typeof (T)))
? new SpecificAndFastCalculator<T>() //Compiler Error
: new GeneralCalculator<T>();
}
public void Calculate(T input)
{
component.Calculate(input); bla bla
}
}
问题是,如您所见,编译器不接受调用 SpecificAndFastCalculator 的构造函数,因为它不知道 T 是否服从约束 T:ISpecificInterface 即使我在运行时检查它。编译器可以是正确的,还是仅仅因为它不够智能而拒绝代码?
有没有办法将组件字段分配给 SpecificAndFastCalculator ?
据我所见,我有以下选择:
还有其他方法吗?暂时我选择了第三个选项(删除约束),你会建议什么?
答案 0 :(得分:2)
如果您更改CalculatorDecorator<T>
的构造函数,它应该可以工作:
public CalculatorDecorator()
{
component = (ICalculator<T>)(typeof (ISpecificInterface).IsAssignableFrom(typeof (T))
? typeof(SpecificAndFastCalculator<>)
.MakeGenericType(typeof(T))
.GetConstructor(new Type[0])
.Invoke(null)
: new GeneralCalculator<T>());
}
这将使用专门的实现,并仍然确保所有其他地方创建的实例也将使用它。
答案 1 :(得分:0)
您应该能够在没有通用约束的情况下定义SpecificAndFastCalculator,因为在运行时您可以保证它符合ISpecificInterface。
当然,您需要将SpecificAndFastCalculator
运行时转换为ICalculator<T>
,SpecificAndFastCalculator
必须已为给定的T实现ICalculator<T>
。
例如,如果T == Int32,并且您已将SpecificAndFastInt32Calculator定义为:
public class SpecificAndFastInt32Calculator : ICalculator<Int32> { ... }
将此实例转换为ICalculator将在运行时编译和工作。