2009-12-23 65 views
0

我想根据查找表中的值调用方法。这些值将在数据库中查找,并将迭代完成。我试图避免的是:根据查找表中的数据运行函数

foreach (Row r in rows) 
{ 
    if (r["command"] == "Command1") 
     MyClass.Command1(); 
    else if (r["command"] == "Comman2") 
     MyClass.Command2(); 
    else if (r["command"] == "Comman3") 
     MyClass.Command3(); 
} 

这是我要支持遗留代码,但我知道肯定有一个更好的方式来做到这一点。目前代码看起来像上面,但我正在寻找一个更优雅的解决方案。

编辑:

基于下面的建议,我试图做这样的事情:

static void Main(string[] args) 
    { 

     Dictionary<string, Action<MyClass>> myActions = new Dictionary<string,Action<MyClass>>(); 
     myActions.Add("Command1",MyClass.DoCommand1("message1")); 
     myActions.Add("Command2",MyClass.DoCommand1("message2")); 

     myActions["Command1"](); 

    } 

与我的类文件看起来像这样:

public class MyClass 
{ 
    public void DoCommand1(string message) 
    { 
     Console.WriteLine(message); 
    } 

    public void DoCommand2(string message) 
    { 
     Console.WriteLine(message); 
    } 
} 

然而,我我得到语法错误,指出非静态字段,方法或属性MyClass.DoCommand1(string)需要对象引用。有任何想法吗?

请注意我正在使用.NET 2.0框架。

回答

2

您可以使用反射:

string command = (string)r["command"]; 
typeof(MyClass) 
    .GetMethod(command, BindingFlags.Static | BindingFlags.Public) 
    .Invoke (null, null); 

或者你也可以使用委托:

var actionMap = new Dictionary<string, Action<string>> { 
    {"SomeAction", MyClass.SomeAction}, 
    {"SomeAction2", MyClass.SomeAction2}, 
    {"SomeAction3", MyClass.SomeAction3}, 
}; 
actionMap[r["command"]]("SomeString"); 

与代表你得到一个不错的语法,避免反射的性能损失。

UPDATE: 我注意到你正在使用.NET 2.0,你需要做的:

class Program 
{ 
    delegate void PoorManAction (string param); 
    static void Main(string[] args) 
    { 

     Dictionary<string, PoorManAction> actionMap = new Dictionary<string, PoorManAction>(); 
     actionMap.Add("SomeMethod1", MyClass.SomeMethod1); 
     actionMap.Add("SomeMethod2", MyClass.SomeMethod2); 
     actionMap.Add("SomeMethod3", MyClass.SomeMethod3); 
     actionMap.Add("SomeMethod4", MyClass.SomeMethod4); 
     actionMap[r["command"]]("SomeString"); 

    } 
} 

更新2::现在的例子使用方法与所看到的字符串参数更新的问题

+0

我喜欢这个解决方案很多,但我不知道如何申报班级内的代表。你能解释一下吗? – 2009-12-23 22:49:31

+0

委托类型为Action,只需声明一个Dictionary 并用YourClass.MethodName填充它,则不需要执行委托实例化,编译器应该处理该问题。 – albertein 2009-12-23 22:54:27

+0

你能看看我上面的编辑,让我知道我要去哪里错了吗?我使用的是.NET 2.0框架,我不相信Action会一直持续到3.0。 – 2009-12-23 23:10:28

1

您可以使用反射来调用该方法。

typeof (MyClass) 
    .GetMethod((string)r["command"], BindingFlags.Static | BindingFlags.Public) 
    .Invoke(null, null); 
0

您可以使用反射来动态调用该方法。由于使用反射的开销,它可能不会像switch语句那样高效。

1

您应该使用匿名委托生产的委托出与部分(或全部)参数的方法绑定到特定的值:

static void Main(string[] args) 
{ 
    Dictionary<string, Action<MyClass>> myActions = 
     new Dictionary<string,Action<MyClass>>(); 

    myActions.Add("Command1", 
     delegate { MyClass.DoCommand1("message1"); }); 
    myActions.Add("Command2", 
     delegate { MyClass.DoCommand1("message2"); }); 

    myActions["Command1"](); 

}