根据其他变量动态调用方法

时间:2011-11-24 03:35:56

标签: c#

  

可能重复:
  How to Call method using its name?

厌倦了使用switch / case语句。我想知道是否有某种方法可以根据用户提供的值调用方法。明白为什么这是一个坏主意可能有一百万个理由,但这就是我的想法:

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

然后以某种方式调用'method_name'中包含的方法。这甚至可能吗?

7 个答案:

答案 0 :(得分:6)

您可以使用反射:

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

如果您希望类型是动​​态的以及方法,请使用此代替typeof(MyClass)

var type = Type.GetType(type_name);

答案 1 :(得分:5)

很多时候你可以将switch语句重构为词典......

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

可以成为......

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

...

replaceSwitch[value]();

这是一个非常微妙的转变似乎没有太大的收获,但实际上它更好,更好。如果你想知道为什么,这个blog post解释得非常好。

答案 2 :(得分:3)

如果您必须使用switch语句对用户的输入值进行操作,则可以使用具有针对输入值映射的方法列表的字典,而不是反射。

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

答案 3 :(得分:2)

我看到的另一种有趣的方法是使用方法字典来处理(读取避免)switch语句。我从http://www.markhneedham.com/blog/2010/05/30/c-using-a-dictionary-instead-of-if-statements/偷了这个,看起来他们正在使用MVC框架,但适用相同的基本原则

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

答案 4 :(得分:1)

您的样本

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

答案 5 :(得分:0)

如果你认为你可以以某种方式这样做:

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

你错了。您必须分析用户输入并根据该方法调用方法。

答案 6 :(得分:0)

当然,reflection是你的朋友。看看Type.GetMethod()