Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 717
Islam Yahiatene Avatar asked Jul 30 '11 15:07

Islam Yahiatene


2 Answers

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); 
like image 125
StriplingWarrior Avatar answered Sep 29 '22 10:09

StriplingWarrior


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);
  }
like image 33
Islam Yahiatene Avatar answered Sep 29 '22 11:09

Islam Yahiatene