2013-03-08 2 views
14

그래서 저는 최근 표현식 트리를 동적으로 구축하는 작업을 해왔고이 방법을 발견했습니다. 다소 이상하게 보입니다. 처음에 나는 끊임없이Expression.Bind() - 실제로 무엇을합니까?

var left = member is FieldInfo ? Expression.Field(instance, (FieldInfo)member) : Expression.Property(instance, (PropertyInfo)member); 
var right = ... 
var assign = Expression.Assign(left, right); 

의 라인을 따라 코드를 작성 후 "아, 시원이가 내가 필요 정확히이다"생각 예, Expression.PropertyOrField() 전화가 알고 있지만, 그것은 이름으로 멤버를 찾기 위해 반사 다시 왕복을한다 , 어디 일반적으로 이미 MemberInfo 인스턴스가 있습니다.

어쨌든, 나는 Expression.Bind()이 나에게 유용 할 것이라고 생각했지만 실제로 이해하지 못하는 것을합니다. 다음 코드를 감안할 때 :

void Main() 
{ 
    var m = typeof(Foo).GetField("Bar"); 
    Expression.Bind(m, Expression.Constant("")).Dump(); 
} 

public class Foo 
{ 
    public string Bar; 
} 

MemberAssignment 표현 Bar = ""을 생산하고 있습니다. 그러나 인스턴스 및 정적 참조가 없습니다. Foo에이 표현식을 어떻게 적용할까요? 나는이 방법을 사용한 예를 찾을 수 없다.

답변

14

개체 - 이니셜 라이저 식. '

내가 할 수

다음
public class Foo 
{ 
    public int Property { get; set; } 
} 

당신이 할 수 있습니다 :

i => new Foo { Property = i } 

올드 : 같은 것이

var parameter = Expression.Parameter(typeof(int), "i"); 
var newExpr = Expression.New(typeof(Foo)); 
var bindExprs = new[] 
    { 
     Expression.Bind(typeof(Foo).GetProperty("Property"), parameter) 
     // You can bind more properties here if you like. 
    }; 

var body = Expression.MemberInit(newExpr, bindExprs); 
var lambda = Expression.Lambda<Func<int, Foo>>(body, parameter); 

의 당신이 가지고 있다고 가정 해 봅시다 너를 도우 라. 당신이 해결하기로 결정한 "성능 문제"를 olve하십시오 (Expression.PropertyOrField를 사용하면 실제로 응용 프로그램에서 병목 현상이 발생합니까? 나는 다소 회의적이다.) (EDIT : Expression Optimization은 사용자가 원하는대로 Expression.MakeMemberAccess가 필요한 것임을 잘못 알고있는 사과입니다.하지만 으로 알려줍니다. 무엇 Expression.Bind가 유용합니다.

+2

oooh ... 나는 그게 그것이라고 생각하지만, 나는 그것을 수용하는'Expression.New()'의 오버로드를 예상하고 있었다. 그것은 완전히 다른 부름이 될 수있는 나에게 발생하지 않았습니다. –

+0

'PropertyOrField'를 사용하지 않는 것에 대해 : 그것은 실제로 최적화가 아닙니다. 내 자신의 온건함에 더 비슷해. –

+0

아, 그렇다면, 왜 'MemberInfo'를 취하고 적절한 분기를하는 작은 도우미를 쓰지 않으시겠습니까? – Ani

관련 문제