开发者

The binary operator Multiply is not defined for the types 'System.Int32' and 'System.Double'.

开发者 https://www.devze.com 2023-03-24 04:41 出处:网络
Why the following code throws an exception at runtime开发者_运维技巧, whereas doing it in the traditional way compiles without problem?

Why the following code throws an exception at runtime开发者_运维技巧, whereas doing it in the traditional way compiles without problem?

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!

I won't use Expression.Convert since I can't determine exactly which expression should be converted.


var left = Expression.Constant(25d);
var right = Expression.Constant(20);
var multiplyExpression = Expression.Multiply(
    left, 
    Expression.Convert(right, left.Type)); 

Or, if you don't know that the left side has higher precision, and you want to always end up with a double result, you could say something like:

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


Well, I figured out how to solve the problem using TypeCode enumeration to determine which node would have higher type precision, then convert the latter node's type to the former's type, and vice versa:

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


Well the error message in your title is telling you why there is an exception.

There is no Expression.Multiply method defined which takes a System.Int32 and a System.Double as arguments.

The * will work because it's lower level and your values will be type cast automatically.


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

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

精彩评论

暂无评论...
验证码 换一张
取 消