Passing function name to Func delegate

I have a very specific situation. I need to accept a function name from user and pass this function name (We already know that this function exists) to another method that handles function calls. This method is named RunMethod and it accepts Func<string, string> method.

I know that I can use something like:

string methodName = "methodName";
MethodInfo mi = this.GetType().GetMethod(methodName);
mi.Invoke(this, null);

But in this case I would have to change the RunMethod method and it's not an option because of existing code using it.

So how do I pass a string as method name to another method that accepts Func<string, string>?

A simplified implementation:

static void Main(string[] args)
{
    var pr = new Program();

    Console.WriteLine("Enter a method name: ");

    // user enters a method name
    string input = Console.ReadLine();

    // Can accept Method1 or Method2 as parameter
    // But we need to pass the "input"
    RunMethod(Method1);

    Console.WriteLine("Press any key to exit");
    Console.ReadKey();
}

static void RunMethod(Func<string, string> method)
{
    Console.WriteLine(method("John Doe"));
}

static string Method1(string name)
{
    return "method 1 called : " + name;
}

static string Method2(string name)
{
    return "method 2 called : " + name;
}
Jon Skeet
people
quotationmark

So how do I pass a string as method name to another method that accepts Func<string, string>?

You don't - you create a Func<string, string> instead. You can do that with Delegate.CreateDelegate:

var method = GetType().GetMethod(...);
var func = (Func<string, string>) Delegate.CreateDelegate(
    typeof(Func<string, string>), method);
RunMethod(func);

Note that this assumes you've already figured out how to get the method appropriately - in your sample code, your methods are private so you'd need to pass BindingFlags.Static | BindingFlags.NonPublic into the GetMethod call.

Complete example:

using System;
using System.Reflection;

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Enter a method name: ");

        // user enters a method name
        string input = Console.ReadLine();

        var method = typeof(Program).GetMethod(input,
            BindingFlags.Static | BindingFlags.NonPublic);
        var func = (Func<string, string>) Delegate.CreateDelegate(
            typeof(Func<string, string>), method);
        RunMethod(func);
    }

    static void RunMethod(Func<string, string> method)
    {
        Console.WriteLine(method("John Doe"));
    }

    static string Method1(string name)
    {
        return "method 1 called : " + name;
    }

    static string Method2(string name)
    {
        return "method 2 called : " + name;
    }
}

people

See more on this question at Stackoverflow