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

为什么以下代码在运行时抛出exception,而以传统方式执行它会编译没有问题?

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

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

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

那么你标题中的错误信息告诉你为什么会有例外。

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

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

 var left = Expression.Constant(25d); var right = Expression.Constant((double)20); var multiplyExpression = Expression.Multiply(left, right); // works