3

Possible Duplicate:
How to Call method using its name?

Getting sick of using switch/case statements. I'm wondering if there is some way to call a method based on the value provided by the user. Understand that there could be a million reasons why this is a bad idea, but here's what I'm thinking:

Console.Write("What method do you want to call? ");
string method_name = Console.ReadLine();

then somehow call the method contained in 'method_name'. Is this even possible?

Community
  • 1
  • 1
joelc
  • 2,687
  • 5
  • 40
  • 60

7 Answers7

9

You can use reflection:

var type = typeof(MyClass);
var method = type.GetMethod(method_name);
method.Invoke(obj, params);

If you want the type to be dynamic as well as the method then use this instead of typeof(MyClass):

var type = Type.GetType(type_name);
Chris Fulstow
  • 41,170
  • 10
  • 86
  • 110
6

Many times you can refactor switch statements to dictionaries...

switch (caseSwitch)
{
    case 1: 
        Console.WriteLine("Case 1");
        break;
    case 2:
        Console.WriteLine("Case 2");
        break;
    case 3:
        Console.WriteLine("Case 3");
        break;
}

can become ...

var replaceSwitch = new Dictionary<int, Action>
    {
        { 1, () => Console.WriteLine("Case 1") }
        { 2, () => Console.WriteLine("Case 2") }
        { 3, () => Console.WriteLine("Case 3") }
    }

...

replaceSwitch[value]();

This is a very subtle shift that doesn't seem to gain much, but in reality it's much, much better. If you want to know why, this blog post explains it very well.

codeConcussion
  • 12,739
  • 8
  • 49
  • 62
3

Instead of reflection, if you have to act on the user's input value w/o using switch statement, you could use a dictionary having the list of methods mapped against the input value.

    private static void Method1(int x)
    {
        Console.WriteLine(x);
    }

    private static void Method2(int x)
    {
    }

    private static void Method3(int x)
    {
    }

    static void Main(string[] args)
    {
        Dictionary<int, Action<int>> methods = new Dictionary<int, Action<int>>();
        methods.Add(1, Method1);
        methods.Add(2,  Method2);
        methods.Add(3, Method3);


        (methods[1])(1);
    }
Jagannath
  • 3,995
  • 26
  • 30
  • What if the method type is string, and it has multiple parameter.. for example, string emilvalid(string x1, string x2) and string regExp(string erro).. both are returning string.. can u tell me how to do that ... and what to use insted of action.. #Action is only for void methods.. and FUNC is for returning method .. but it is still giving error.. – nikunjM Jul 22 '15 at 15:18
2

Your sample

public class Boss
{
    public void Kick()
    {
        Console.WriteLine("Kick");
    }
    public void Talk(string message)
    {
        Console.WriteLine("Talk " + message);
    }
    public void Run()
    {
        Console.WriteLine("Run");
    }
}

class Program
{
    static void AutoSwitch(object obj, string methodName, params object[] parameters)
    {
        var objType = typeof(obj);
        var method = objType.GetMethod(methodName);
        method.Invoke(obj, parameters);
    }

    static void Main(string[] args)
    {
        var obj = new Boss();

        AutoSwitch(obj, "Talk", "Hello World");
        AutoSwitch(obj, "Kick");
    }
}
Peter PAD
  • 2,252
  • 1
  • 17
  • 20
2

Another interesting way I have seen to handle(read avoid) switch statements differently is to use a dictionary of methods. I stole this from http://www.markhneedham.com/blog/2010/05/30/c-using-a-dictionary-instead-of-if-statements/ and it looks like they are using the MVC framework but the same basic principal applies

public class SomeController
{
private Dictionary<string, Func<UserData,ActionResult>> handleAction = 
    new Dictionary<string, Func<UserData,ActionResult>>
    { { "Back", SaveAction },
      { "Next", NextAction },
      { "Save", SaveAction } };

public ActionResult TheAction(string whichButton, UserData userData)
{
    if(handleAction.ContainsKey(whichButton))
    {
        return handleAction[whichButton](userData);
    }

    throw Exception("");
}

private ActionResult NextAction(UserData userData)
{
    // do cool stuff
}
}
Jeff Lauder
  • 1,247
  • 8
  • 14
0

If you're thinking you could somehow do this:

Console.Write("What method do you want to call? ");
string method_name = Console.ReadLine();
method_name();

You are mistaken. You have to analyze the user input and call a method based on that.

N0ug4t
  • 191
  • 1
  • 12
0

Sure, reflection is your friend. Have a look at Type.GetMethod().

ChrisWue
  • 18,612
  • 4
  • 58
  • 83