2009-12-23 38 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"](); 

}