C# - 物业类型的多种可能性

时间:2017-06-06 17:20:37

标签: c# generics interface properties

我有一个名为“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;
        }
    }
}

好吧,编译错误,显然直接强制转换不适用于泛型。这个问题可以通过首先投射到对象来解决,但我很确定这将是一个糟糕的方法,而不是一个好的练习。您有什么建议我如何以一种好的方式解决这个问题?

1 个答案:

答案 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进行隐式或显式转换的类型。

但是,使用动态对象有两个主要问题:

  1. 类型安全:无论TU的实际类型如何,此代码都将进行编译。如果类型不兼容(他们没有共同的操作符),您将在运行时获得异常。

  2. 性能:动态objetcs构建表达式树,这些树在首次使用时编译,而不是在运行时缓存。这意味着,您的程序必须在运行时编译,这会以减慢代码的速度结束(但是,对于所使用的每种类型组合,只需执行一次)。

  3. 有关其他信息,请阅读有关dynamic和的文章 expression trees