2011-07-30 2 views
9

다음과 같은 코드가 런타임시 예외를 던지는 이유는 전통적인 방식으로 문제없이 컴파일하는 이유입니다. 내가 정확히 변환되어야하는 표현 결정할 수 없기 때문에이진 연산자 인 Multiply가 'System.Int32'및 'System.Double'형식에 대해 정의되지 않았습니다.

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

전통적으로 컴파일러는 변환 할면을 결정하기 위해 형식 우선 순위 규칙을 사용하는 'Expression.Convert'의 (도덕적으로 등가 인) 요소를 삽입합니다. –

+0

이 경우 C# 컴파일러가 변환 한 표현식은 무엇입니까? –

+1

변환 할 필요가있는 쪽을 알려주는 "곱하기"유형을 확인하십시오. – MerickOWA

답변

7

글쎄, 어떤 노드가 높은 형식 정밀도를 결정하기 위해 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); 
    } 
+0

오 댐 ... TypeCode는 Windows 스토어에서 사용할 수 없습니다. 너무 가까이 ...; –

0

글 제목에 오류 메시지가 표시되어 예외가있는 이유를 설명합니다.

인수로 System.Int32System.Double을 취하는 정의 된 Expression.Multiply 메서드가 없습니다.

낮은 레벨이고 값이 자동으로 타입 캐스트되기 때문에 *이 작동합니다. 당신이 왼쪽보다 높은 정밀도를 가지고 모르고, 당신은 항상 double 결과와 끝까지하려는 경우, 당신은 말할 수

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

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

이것은 직접 수행 할 수 없으며 Expression.Convert를 어떻게 든 호출해야합니다. –

7

var left = Expression.Constant(25d); 
var right = Expression.Constant(20); 
var multiplyExpression = Expression.Multiply(
    left, 
    Expression.Convert(right, left.Type)); 
또는 뭔가 같은 :

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

글쎄, 이것은 좋아 보이는데, 피연산자가 10 진수 float 유형 인 경우 어떻게 할 수 있습니까? –

+1

@Islam Ibrahim : 여러 가지 가능성이 있으며 일반적으로 가장 간단한 전략을 사용하는 것이 가장 좋습니다. 아마도 귀하가 요구 사항에 대해 더 많은 정보를 공유하고이를 위해 무엇을 사용하는지에 대해, 우리는 당신이 일치시킬 솔루션을 찾도록 도울 수 있습니다. 예를 들어, 어떤 유형을 사전에 끝내고 싶은지 또는 입력에 따라 변경 될지를 알고 계십니까? – StriplingWarrior

관련 문제