由於傳遞到Zap
方法中的表達式是一棵樹,因此只需使用Expression Tree Visitor來遍歷樹,並在表達式中查找第一個ConstantExpression
。它可能會在下面的序列:
(((source.Body as MemberExpression).Expression as MemberExpression).Expression as ConstantExpression).Value
注意,bar
實例由一個閉合,其作爲與該實例的一員,其是其中第二MemberExpression來自內部類實現捕獲。
編輯
然後,你必須從產生的閉合拿到野外,像這樣:
static void Main(string[] args)
{
var bar = new Bar();
bar.Foo = "Hello, Zap";
Zap(() => bar.Foo);
}
private class Bar
{
public String Foo { get; set; }
}
public static void Zap<T>(Expression<Func<T>> source)
{
var param = (((source.Body as MemberExpression).Expression as MemberExpression).Expression as ConstantExpression).Value;
var type = param.GetType();
// Note that the C# compiler creates the field of the closure class
// with the name of local variable that was captured in Main()
var field = type.GetField("bar");
var bar = field.GetValue(param) as Bar;
Debug.Assert(bar != null);
Console.WriteLine(bar.Foo);
}
如果我調用'Zap((()=> 1)'會怎麼樣? – 2010-01-13 19:16:10
然後我不會嘗試打電話給bar.Zim()。 :-)真的,我想看看傳入的東西是否是一個Bar實例,如果是,請調用一個實例方法。可能? – 2010-01-13 19:19:28