简体   繁体   中英

Run Function Based off of Data in a Lookup Table

I want to call a method based on a value in a lookup table. The values will be looked up in a database, and will be iterated through. What I am trying to avoid is this:

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

This is legacy code that I have to support, but I know there surely is a better way to do this. Currently the code looks like the above but I am looking for a more elegant solution.

EDIT:

Based on the suggestions below, I am trying to do something like this:

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

    }

with my class file looking like this:

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

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

However, I am getting syntax errors saying that an object reference is required for the nonstatic filed, method, or property MyClass.DoCommand1(string). Any ideas?

Please note I am using the .NET 2.0 framework.

You can use reflection:

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

Or you can also use delegates:

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

With delegates you get a nice syntax and avoid the performance hit of reflection.

UPDATE: I noticed that you're using .NET 2.0, you need to do:

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

    }
}

UPDATE 2: : Now the example uses methods with a string parameter as seen in the updated question

You can use reflection to call the method.

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

You should use anonymous delegates to produce a delegate out of a method with some (or all) arguments bound to specific values:

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

}

You could use reflection to dynamically call the method. It probably would not be as efficient as a switch statement because of the overhead of using reflection.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM