2011-03-23 10 views
10

Tengo una Acción y me pregunto cómo podría acceder a la instancia que llama al método.Delegado de acción. Cómo obtener la instancia que llama al método

Ejemplo:

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" 
    } 

Gracias

Respuesta

8

Creo que estás en busca de la propiedad Delegate.Target.

EDITAR: Bien, ahora veo lo que buscas, y necesitas un árbol de expresiones que represente la acción. A continuación, puede encontrar el objetivo de la llamada al método como otro árbol de expresión, construir un LambdaExpression de eso, compilar y ejecutar, y ver el resultado:

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

Tenga en cuenta que esto es increíblemente frágil - pero debería funcionar en casos simples.

+0

No, Delegate.Target es la clase en la que se ha invocado la acción. Quiero la instancia que llama al método. –

+0

@Jean En ese caso, no entiendo lo que buscas. Proporcione un ejemplo breve pero * completo * –

+0

@Jean: El motivo por el que esto no funciona para usted es porque va a cerrar la llamada al método en una lambda inútil. Pruebe 'FindInstance (InstanceOfAClass.Method)' (sin lambda) y funcionará como lo desee. Si desea que funcione con la sintaxis lambda, tendrá que aceptar un parámetro de tipo 'Expresión ' y recorrer el árbol de expresiones. –

3

En realidad, no sé si puede hacerlo de esta manera. La clase Delegate contiene solo dos propiedades: Target y Method. El acceso al Target no funcionará porque está creando un nuevo método anónimo, por lo que la propiedad devolverá la clase en la que se llama al método FindInstance.

intentar algo como esto en su lugar:

FindInstance(this.MyInstance.DoSomething); 

y luego acceder a la propiedad Target de la siguiente manera:

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

Lo sentimos, pero el objetivo no es la instancia sino la información sobre la instancia. – Jacob

Cuestiones relacionadas