2011-03-23 96 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

相关问题