Функция запуска на основе данных в таблице поиска - PullRequest
0 голосов
/ 24 декабря 2009

Я хочу вызвать метод, основанный на значении в таблице поиска. Значения будут найдены в базе данных и будут повторяться. Чего я пытаюсь избежать, так это:

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

Это устаревший код, который я должен поддерживать, но я знаю, что, безусловно, есть лучший способ сделать это. В настоящее время код выглядит как выше, но я ищу более элегантное решение.

EDIT:

Исходя из приведенных ниже предложений, я пытаюсь сделать что-то вроде этого:

    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 framework.

Ответы [ 4 ]

2 голосов
/ 24 декабря 2009

Вы можете использовать отражение:

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: : Теперь в примере используются методы со строковым параметром, как показано в обновленном вопросе

1 голос
/ 24 декабря 2009

Вы должны использовать анонимных делегатов для создания делегата из метода с некоторыми (или всеми) аргументами, привязанными к определенным значениям:

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"]();

}
1 голос
/ 24 декабря 2009

Вы можете использовать отражение для вызова метода.

typeof (MyClass)
    .GetMethod((string)r["command"], BindingFlags.Static | BindingFlags.Public)
    .Invoke(null, null);
0 голосов
/ 24 декабря 2009

Вы можете использовать отражение для динамического вызова метода. Вероятно, он не будет столь же эффективным, как оператор switch, из-за накладных расходов на использование отражения.

...