2013-04-25 1 views
30

속성의 이름에서 런타임에 중첩 된 속성에 대한 람다 식을 만들려고합니다. 그러나 나는 주어진하고 모든 Foo의 종류와 문자열 "myBar.name"문자열에서 중첩 된 속성에 대한 LambdaExpression을 구성하십시오.

는 경우가

class Foo 
{ 
    public Bar myBar { get; set; } 
} 
class Bar 
{ 
    public string name { get; set; } 
} 

: 클래스로

var expression = CreateExpression<Foo, object>(foo => foo.myBar.name); 

private static Expression CreateExpression<TEntity, TReturn>(Expression<Func<TEntity, TReturn>> expression) 
{ 
    return (expression as Expression); 
} 

: 나는 기본적으로 지정된 람다 식을 만들려고하고 있어요 단지 "myBar" 값을 필요로하는 것과 같은 정상적인 속성이었습니다. 다음을 사용할 수 있습니다 :

private static LambdaExpression GetPropertyAccessLambda(Type type, string propertyName) 
{ 
    ParameterExpression odataItParameter = Expression.Parameter(type, "$it"); 
    MemberExpression propertyAccess = Expression.Property(odataItParameter, propertyName); 
    return Expression.Lambda(propertyAccess, odataItParameter); 
} 

그러나이 코드는 중첩 된 속성에는 작동하지 않으며 foo.myBar.name의 작업을 수행하는 LambdaExpression을 만드는 방법을 잘 모르겠습니다.

GetExpression(Expression.Call(GetExpression(Foo, "myBar"), "name")) 

하지만 실행시에이 작업을 수행 할 수있는 더 좋은 방법이 있다면 그것은 모든 작업을 진행하거나하는 방법을 작동하지 수

는 나는 이런 식으로 뭔가있을 것 같아 .

답변

62

당신은 의미합니까 : 예를 들어

static LambdaExpression CreateExpression(Type type, string propertyName) { 
    var param = Expression.Parameter(type, "x"); 
    Expression body = param; 
    foreach (var member in propertyName.Split('.')) { 
     body = Expression.PropertyOrField(body, member); 
    } 
    return Expression.Lambda(body, param); 
} 

:

class Foo { 
    public Bar myBar { get; set; } 
} 
class Bar { 
    public string name { get; set; } 
} 
static void Main() { 
    var expression = CreateExpression(typeof(Foo), "myBar.name"); 
    // x => x.myBar.name 
} 

?

+0

네가 찾고있는 바로 그 것이다. 내 실수는 중첩 된 속성을 가져 오기 전에 (Call을 사용하여) 본문 표현식을 호출해야한다고 생각했다. – Seph

+0

위대한 답변! 명확함을 위해 +1 – ps2goat

+0

나를 위해 그것을 해결 한 Marc Gravell로부터의 환상적인 대답. 보너스로 resharper가 코드에서 다음을 수행했습니다. var param = Expression.Parameter (type, "x"); expression body = propertyName.Split ('.'). 집계 (param, Expression.PropertyOrField); return Expression.Lambda (body, param); –