Бинарный оператор Multiply не определен для типов «System.Int32» и «System.Double». - PullRequest
10 голосов
/ 30 июля 2011

Почему следующий код генерирует исключение во время выполнения, тогда как выполнение традиционным способом компилируется без проблем?

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 ]

8 голосов
/ 31 июля 2011

Ну, я разобрался, как решить проблему, используя перечисление 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);
  }
8 голосов
/ 30 июля 2011
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); 
0 голосов
/ 30 июля 2011
var left = Expression.Constant(25d);
var right = Expression.Constant((double)20);

var multiplyExpression = Expression.Multiply(left, right); // works
0 голосов
/ 30 июля 2011

Ну, сообщение об ошибке в вашем заголовке говорит вам, почему есть исключение.

Не определен метод Expression.Multiply, который принимает System.Int32 и System.Double в качестве аргументов.

* будет работать, потому что это более низкий уровень, и ваши значения будут автоматически приводиться к типу.

...