C# Action/Function List

2019-02-28 13:54发布

问题:

I have a program that has to execute a function acording to a Enum and I'm wondering If there's another way to it than this:

enum FunctionType
{
 Addition = 0,
 Substraction = 1,
 Mutiplication = 2,
 Division = 3
}
void ExecuteFunction(FunctionType Function)
{
  switch(Function)
  {
    case FunctionType.Addition: Addition();
    break;
    case FunctionType.Substraction: Subsctration();
    break;      
    ...
    default: ...  
  }
}

(This is not the code i'm using, it's just to represent what I want to do). This approach should work fine, but what happens when you have much more functions? I don't want to have a 50 line switch. So I want to know if there's a way to simplify it, something like this maybe:

enum FunctionType : Action
{
 Addition = new Action(Addition);
 Substraction = new Action(Substraction);
 ....
}
void ExecuteFunction(FunctionType Function)
{
 (Action)Function.Invoke();
}

No switch is needed and what could be 50 lines turn into 1 line. But this is not possible to do, only numeric types are acceped as enums. I think it's posible to have a List<T> of actions but that would require to add each action to the list at runetime.

EDIT: I've found on a source code a way this is done, but I can't really understand It. This is what I get: They create a custom Attribute that contains a string (The method name) and on the methods they do:

[CustomAtrribute("name")]
void Method()
{    
}

Then I don't know how this is called by it's name, I guess some kind of refelction, bu I don't know how to find the info about this.

EDIT2: I found the way I want to do this, I'll add an interface with a function, then implement that interface with the code inside the function and Use a Dictionary<Enum, Interface> to call it. I don't know If I should answer my own question, anyways, thanks to everyone one helped me.

回答1:

Can't say I would recommend doing this but:

public static class Functions
{
    public static Func<int, int, int> Add = (x, y) => { return x + y; };
}

Then you just call Functions.Add(1,1)

If you really have to use an enum for it then you could do:

public static class Functions
{
    public static void Add()
    {
        Debug.Print("Add");
    }

    public static void Subtract()
    {
        Debug.Print("Subtract");
    }

    public enum Function
    {
        Add,
        Subtract
    }

    public static void Execute(Function function)
    {
        typeof(Functions).GetMethod(function.ToString()).Invoke(null, null);
    }
}

Then Functions.Execute(Functions.Function.Add) (extra functions is because my enum was inside the Functions class).



回答2:

If your functions contain same signature then you can do something like this

enum FunctionType
{
 Addition = 0,
 Substraction = 1,
 Mutiplication = 2,
 Division = 3
}
void ExecuteFunction(FunctionType Function)
{
  //variable will contain function to execute
  public Func<int, int, int> functionToExecute= null;

  switch(Function)
  {
    case FunctionType.Addition: functionToExecute=Addition;
    break;
    case FunctionType.Substraction: functionToExecute=Subsctration;
    break;      
    ...
    default: ...  
  }

  //Checking if not reached default case
  if(functionToExecute!=null)
  {
   var result= functionToExecute(para1,para2);
   ...............
  }


}