有没有一种有效的方法来调用基于C#/ .NET中字符串值的方法?

时间:2017-07-23 22:27:16

标签: c# .net

最基本的方法是通过switch语句:

switch(action)
{
    case "Action1":
        DoAction1();
        return;
    case "Action2":
        DoAction2();
        return;
    case "Action3":
        DoAction3();
        return;
}

这不仅非常混乱,而且通过要求更改类以添加新功能来打破Open / Closed Principal。 可以通过将switch语句放在虚方法中来解决这个问题,但它仍然很混乱。

我知道使用委托可以实现类似的效果,但在我的情况下,字符串是从外部文件加载的,所以这不是一个选项。

编辑:为了清楚起见,我不介意答案是否需要手动将字符串“映射”到方法,只要可以在不修改基类的情况下添加新方法,并且不会像上面的switch语句那样产生代码味道。

2 个答案:

答案 0 :(得分:0)

您可以使用反射来执行动态方法调用,假设您的字符串与方法名称完全匹配:

Type _t = this.GetType();
MethodInfo _methodInfo = _t.GetMethod(method);
var result = _methodInfo.Invoke(this, new object[] {  });

在上面的代码中,您将获得当前类对象的类型,然后获取该方法。方法变量将是您要调用的方法的名称。在调用中,对象数组是您需要传递给调用方法的参数。

我有一个示例要点here

答案 1 :(得分:0)

你可以使用反射,但反射是非常开放的....如果你想控制映射然后使用像

这样的东西
   public class Invoker
    {
        Dictionary<string, Action> _actions = new Dictionary<string, Action>();

        public void Do(string action)
        {
            if (_actions.ContainsKey(action)) _actions[action]();
            else
            {
                // no match 
            }
        }

        public void AddAction(string action, Action f)
        {
            _actions.Add(action, f);
        }
}

然后可以使用

var invoker = new Invoker()
invoker.AddAction("Action1", DoAction1);
invoker.AddAction("Action2", DoAction2);

另一种选择是使用属性,这将使用映射

提供更受控制的反射方式