2016-12-18 2 views
3

표현식이 Expression<Func<TFoo, string>> exp 인 메소드가 있습니다.동일한 유형의 두 표현식을 병합합니다 (부울 제외)

나는이

MyMethod(o => o.SomeStringProperty); 

처럼 하나의 표현을 전달할 수 있습니다 그러나 지금은 (두 개의 문자열 속성에서) 표현을 결합하고 내가 찾은 다른 모든 예 Expression<Func<Foo, bool>>이다이 방법

를 전달하고자합니다.

나는
Expression<Func<TFoo, string>> fn1 = x => x.SomeStringProperty1; 
Expression<Func<TFoo, string>> fn2 = x => x.SomeStringProperty2; 

var body = Expression.Coalesce(fn1.Body, fn2.Body); 
var lambda = Expression.Lambda<Func<TFoo, string>>(body, fn1.Parameters[0]); 

을 시도했지만 표현의 거의 모든 기능은 예외가 발생합니다. 이 작업을 결합하는 방법은 무엇입니까?

+0

같은

public static class ExpressionUtils { public static Expression ReplaceParameter(this Expression expression, ParameterExpression source, Expression target) { return new ParameterReplacer { Source = source, Target = target }.Visit(expression); } class ParameterReplacer : ExpressionVisitor { public ParameterExpression Source; public Expression Target; protected override Expression VisitParameter(ParameterExpression node) { return node == Source ? Target : base.VisitParameter(node); } } } 

을 의미합니까 :

두 번째 방법은 첫 번째 람다 식의 매개 변수에 두 번째 람다 식 본체를 리 바인드하는 간단한 매개 변수 대체물 도우미를 사용 두 가지 표현? 귀하의 예제에서, 당신은 단지 두 개의 인수를 가진 메소드를 호출하고 있습니다. –

+1

@IvanStoev : 내 질문 업데이트 –

답변

1

람다 식을 결합 할 때는 결과 식에 인스턴스이 바인딩되어 있는지 확인해야합니다.

두 가지 방법으로 달성 할 수 있습니다.

첫 번째

Expression.Invoke 방법을 사용하는 것입니다

var body = Expression.Coalesce(fn1.Body, Expression.Invoke(fn2, fn1.Parameters[0])); 
var lambda = Expression.Lambda<Func<TFoo, string>>(body, fn1.Parameters[0]); 

이것은 가장 간단한 방법을하지만, 호출 식을 지원하지 않는 엔티티 프레임 워크와 유사한 지원되지 않는 표현을 만듭니다. 당신은 "결합"은 무엇을이

var body = Expression.Coalesce(fn1.Body, 
    fn2.Body.ReplaceParameter(fn2.Parameters[0], fn1.Parameters[0])); 
var lambda = Expression.Lambda<Func<TFoo, string>>(body, fn1.Parameters[0]); 
관련 문제