2011-03-23 98 views
10

我有一個Action,我不知道如何訪問調用該方法的實例。行動委託。如何獲得調用方法的實例

例:

this.FindInstance(() => this.InstanceOfAClass.Method()); 
this.FindInstance(() => this.InstanceOfAClass2.Method()); 
this.FindInstance(() => this.InstanceOfAClass3.Method()); 



    public void FindInstance(Action action) 
    { 
     // The action is this.InstanceOfAClass.Method(); and I want to get the "Instance" 
     // from "action" 
    } 

謝謝

回答

8

我認爲你正在尋找的Delegate.Target財產。

編輯:好的,現在我看到你以後,你需要這些動作的表達式樹。然後你就可以找到方法調用另一個表達式樹的目標,建立從一個LambdaExpression,編譯並執行它,看到的結果:

using System; 
using System.Linq.Expressions; 

class Test 
{ 
    static string someValue; 

    static void Main() 
    { 
     someValue = "target value"; 

     DisplayCallTarget(() => someValue.Replace("x", "y")); 
    } 

    static void DisplayCallTarget(Expression<Action> action) 
    { 
     // TODO: *Lots* of validation 
     MethodCallExpression call = (MethodCallExpression) action.Body; 

     LambdaExpression targetOnly = Expression.Lambda(call.Object, null); 
     Delegate compiled = targetOnly.Compile(); 
     object result = compiled.DynamicInvoke(null); 
     Console.WriteLine(result); 
    } 
} 

注意,這是令人難以置信的脆弱 - 但它應該工作在簡單的情況。

+0

沒有,Delegate.Target是其中已經調用操作的類。我想要調用該方法的實例。 – 2011-03-23 18:04:32

+0

@Jean在這種情況下,我不明白你在做什麼。請提供一個簡短但完整的示例 – 2011-03-23 18:06:52

+0

@Jean:這不適合你的原因是因爲你會用一個相當無用的lambda包裝方法調用。嘗試'FindInstance(InstanceOfAClass.Method)'(沒有lambda),它會按你的意願工作。如果您希望它使用lambda語法,則需要接受「Expression 」類型的參數,然後遍歷表達式樹。 – 2011-03-23 18:12:48

3

其實我不知道,如果你能以這種方式做到這一點。 Delegate類只包含兩個屬性:TargetMethod。訪問Target因爲你正在創建一個新的匿名方法,所以屬性將返回在FindInstance方法被稱爲類將無法正常工作。

嘗試這樣代替:

FindInstance(this.MyInstance.DoSomething); 

,然後訪問Target屬性,如下所示:

public void FindInstance(Action action) 
{ 
    dynamic instance = action.Target; 
    Console.WriteLine(instance.Property1); 
} 
+0

對不起,但目標不是實例,而是關於實例的信息。 – Jacob 2015-09-05 12:37:52

相關問題