没有为类型'System.Int32'和'System.Double'定义二元运算符Multiply。

时间:2011-07-30 15:29:27

标签: c# linq expression

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

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,因为我无法准确确定应该转换哪个表达式。

4 个答案:

答案 0 :(得分:8)

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); 

答案 1 :(得分:8)

好吧,我想出了如何使用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);
  }

答案 2 :(得分:0)

标题中的错误消息告诉您为什么会有异常。

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

*会有效,因为它的级别较低,您的值会自动输入。

答案 3 :(得分:0)

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

var multiplyExpression = Expression.Multiply(left, right); // works