【问题标题】:The binary operator Multiply is not defined for the types 'System.Int32' and 'System.Double'.没有为“System.Int32”和“System.Double”类型定义二元运算符 Multiply。
【发布时间】:2011-07-30 15:29:27
【问题描述】:

为什么下面的代码在运行时抛出异常,而以传统方式编译却没有问题?

var left = Expression.Constant(25d);
var right = Expression.Constant(20);

// Throws an InvalidOperationException!
var multiplyExpression = Expression.Multiply(left, right); 

var multiply = 25d * 20;
Debug.WriteLine(multiply.ToString()); // Works normally!

我不会使用Expression.Convert,因为我无法准确确定应该转换哪个表达式。

【问题讨论】:

  • 因为以传统方式,编译器会插入(道德等价的)Expression.Convert - 使用类型优先规则来确定要转换哪一侧。
  • 在这种情况下 C# 编译器会转换哪个表达式?
  • 只检查“乘法”的类型,它会告诉你哪一边需要转换。

标签: c# linq expression


【解决方案1】:
var left = Expression.Constant(25d);
var right = Expression.Constant(20);
var multiplyExpression = Expression.Multiply(
    left, 
    Expression.Convert(right, left.Type)); 

或者,如果您不知道左侧的精度更高,并且您希望始终得到 double 结果,您可以这样说:

Expression left = Expression.Constant(2);
Expression right = Expression.Constant(25.1);
left = Expression.Convert(left, typeof(double));
right = Expression.Convert(right, typeof(double));
var multiplyExpression = Expression.Multiply(left, right); 

【讨论】:

  • 嗯,这看起来不错,但是如果操作数的类型是浮点数、十进制数怎么办?
  • @Islam Ibrahim:有很多可能性,通常最好采用适合您目的的最简单策略。也许如果您分享有关您的要求以及用途的更多信息,我们可以帮助您找到匹配的解决方案。例如,您是否提前知道最终要使用哪种类型,或者会根据输入而改变?
【解决方案2】:

好吧,我想出了如何解决这个问题,使用 TypeCode 枚举来确定哪个节点的类型精度更高,然后将后者节点的类型转换为前者的类型,反之亦然:

  private static void Visit(ref Expression left, ref Expression right)
  {
     var leftTypeCode = Type.GetTypeCode(left.Type);
     var rightTypeCode = Type.GetTypeCode(right.Type);

     if (leftTypeCode == rightTypeCode)
         return;

     if (leftTypeCode > rightTypeCode)
        right = Expression.Convert(right, left.Type);
     else
        left = Expression.Convert(left, right.Type);
  }

【讨论】:

  • 天啊... TypeCode 在 Windows 应用商店中不可用。这么近……;(
【解决方案3】:

你标题中的错误信息告诉你为什么会出现异常。

没有定义将System.Int32System.Double 作为参数的Expression.Multiply 方法。

* 将起作用,因为它的级别较低,并且您的值将自动进行类型转换。

【讨论】:

    【解决方案4】:
    var left = Expression.Constant(25d);
    var right = Expression.Constant((double)20);
    
    var multiplyExpression = Expression.Multiply(left, right); // works
    

    【讨论】:

    • 这不能直接完成,我应该以某种方式调用 Expression.Convert。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-19
    • 1970-01-01
    相关资源
    最近更新 更多