I have an Action and I wonder how could I access the instance that call the method.
Exemple:
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"
}
Thank you
The Action delegate is generally used for those methods which do not contain any return value, or in other words, Action delegate is used with those methods whose return type is void. It can also contain parameters of the same type or of different types.
A delegate can be declared using the delegate keyword followed by a function signature, as shown below. The following declares a delegate named MyDelegate . public delegate void MyDelegate(string msg); Above, we have declared a delegate MyDelegate with a void return type and a string parameter.
A delegate is a type that represents references to methods with a particular parameter list and return type. When you instantiate a delegate, you can associate its instance with any method with a compatible signature and return type. You can invoke (or call) the method through the delegate instance.
Use the new keyword to instantiate a delegate. When creating a delegate, the argument passed to the new expression is written similar to a method call, but without the arguments to the method.
I think you're looking for the Delegate.Target
property.
EDIT: Okay, now I see what you're after, and you need an expression tree representing the action. Then you can find the target of the method call as another expression tree, build a LambdaExpression from that, compile and execute it, and see the result:
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);
}
}
Note that this is incredibly brittle - but it should work in simple cases.
Actually I don't know if you can do it in this way. Delegate
class contains only two properties: Target
and Method
. Accessing Target
won't work because you are creating a new anonymous method, so the property will return the class in which FindInstance
method is called.
Try something like this instead:
FindInstance(this.MyInstance.DoSomething);
And then access the Target
property as follows:
public void FindInstance(Action action)
{
dynamic instance = action.Target;
Console.WriteLine(instance.Property1);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With