我有一个名为“IOperation”的界面
interface IOperation<T,U>
{
T FirstOperand { get; set; }
U SecondOperand { get; set; }
int Result { get; }
}
FirstOperand和SecondOperand可以是int或另一个IOperation。实施此类行为的最佳方式是什么?继承类的示例:
class Subtraction<T, U> : IOperation<T, U>
{
public T FirstOperand { get; set; }
public U SecondOperand { get; set; }
public int Result
{
get
{
var first = 0;
var second = 0;
if(FirstOperand is Double)
{
first = (Double) FirstOperand;
}
if(FirstOperand is IOperation)
{
first = (IOperation) FirstOperand;
}
// TODO: Same thing with SecondOperand
return FirstOperand - SecondOperand;
}
}
}
好吧,编译错误,显然直接强制转换不适用于泛型。这个问题可以通过首先投射到对象来解决,但我很确定这将是一个糟糕的方法,而不是一个好的练习。您有什么建议我如何以一种好的方式解决这个问题?
答案 0 :(得分:0)
有一种方法可以做到(虽然我不推荐)。
您可以将两个操作数打包在动态对象中。这将编译:
class Subtraction<T, U> : IOperation<T, U>
{
public T FirstOperand { get; set; }
public U SecondOperand { get; set; }
public int Result
{
get
{
dynamic first = FirstOperand;
dynamic second = SecondOperand;
return (int)(first - second);
}
}
}
它适用于对于相应类型(即operator -
和int
)具有double
重载且对int
进行隐式或显式转换的类型。
但是,使用动态对象有两个主要问题:
类型安全:无论T
和U
的实际类型如何,此代码都将进行编译。如果类型不兼容(他们没有共同的操作符),您将在运行时获得异常。
性能:动态objetcs构建表达式树,这些树在首次使用时编译,而不是在运行时缓存。这意味着,您的程序必须在运行时编译,这会以减慢代码的速度结束(但是,对于所使用的每种类型组合,只需执行一次)。
有关其他信息,请阅读有关dynamic和的文章 expression trees