views:

70

answers:

2

Is there a way to use Action to call a method based on a string value that contains the name of that method?

+5  A: 

Action<T> is just a delegate type that could point to a given method. If you want to call a method whose name is known only at runtime, stored in a string variable, you need have to use reflection:

class Program
{
    static void Main(string[] args)
    {
        string nameOfTheMethodToCall = "Test";
        typeof(Program).InvokeMember(
            nameOfTheMethodToCall, 
            BindingFlags.NonPublic | BindingFlags.InvokeMethod | BindingFlags.Static, 
            null, 
            null, 
            null);
    }

    static void Test()
    {
        Console.WriteLine("Hello from Test method");
    }
}


As suggested by @Andrew you could use Delegate.CreateDelegate to create a delegate type from a MethodInfo:

class Program
{
    static void Main(string[] args)
    {
        string nameOfTheMethodToCall = "Test";
        var mi = typeof(Program).GetMethod(nameOfTheMethodToCall, BindingFlags.NonPublic | BindingFlags.InvokeMethod | BindingFlags.Static);
        var del = (Action)Delegate.CreateDelegate(typeof(Action), mi);
        del();
    }

    static void Test()
    {
        Console.WriteLine("Hello from Test method");
    }
}
Darin Dimitrov
If you use `Delegate.CreateDelegate` you can create a delegate for your `MethodInfo` like the OP requested.
Andrew Hare
Great remark @Andrew. I've updated my answer to give an example of this.
Darin Dimitrov
Nicely done :) (+1 by the way)
Andrew Hare
+2  A: 

I don't think you really want an Action<T> just a regular method.

public void CallMethod<T>(T instance, string methodName) { 
    MethodInfo method = typeof(T).GetMethod(methodName);
    if (method != null) {
        method.Invoke(instance, null);
    }
}
Bob