2013-03-08 82 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

Object-Initializer表達式

比方說,你有:

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

然後,你可以這樣做:

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); 

是這樣的:

i => new Foo { Property = i } 

老:

我可以」幫助你你會決定解決的「性能問題」(將使用Expression.PropertyOrField真的在你的應用程序中引入瓶頸?我有點懷疑。你應該在過早優化之前確定這一點)編輯:錯誤地認爲這是一個性能優化,並且你已經發現你自己,Expression.MakeMemberAccess是你需要的)的道歉,但我可以告訴你什麼Expression.Bind是有用的。

+2

oooh ...我認爲這就是它,但是我期待'Expression.New()'接受這個過載。我不覺得這可能是一個完全不同的電話。 – 2013-03-08 16:15:33

+0

關於不使用'PropertyOrField':這不是真正的優化。更像是爲了我自己的理智。 – 2013-03-08 16:17:54

+0

啊,如果是這樣的話,那麼爲什麼不寫一個帶有'MemberInfo'和分支的小助手呢? – Ani 2013-03-08 16:20:51

相關問題