2016-08-19 31 views
1

我有一个具有执行功能acording一个枚举,我想知道如果有另一种方式把它比这个程序:C#动作/功能列表

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: ... 
    } 
} 

(这不是我的代码正在使用,它只是代表我想要做的事情)。 这种方法应该可以正常工作,但是当你有更多的功能时会发生什么?我不想要一个50线开关。所以我想知道是否有简化它的方式,这样的事情也许:

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

无需开关,这可能是50行变为1行。但这是不可能的,只有数字类型被加入为枚举。 我认为可以有一个List<T>的动作,但是需要在runetime将每个动作添加到列表中。

编辑: 我在源代码中发现了这样做的一种方式,但我无法真正理解它。这就是我得到: 他们创建一个包含string(方法名称)的自定义Attribute和方法,他们做的事:

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

然后,我不知道这是怎么叫通过它的名字,我猜猜某种形式的refelction,我不知道如何找到关于此的信息。编辑2:我找到了我想要做到这一点的方式,我将添加一个带有函数的接口,然后使用函数中的代码实现该接口,然后使用Dictionary<Enum, Interface>来调用它。我不知道我是否应该回答自己的问题,无论如何,感谢大家帮助我。

+4

那么你可以有一个'词典<函数类型,操作>'...但同样,你需要建立起来在执行时。如果方法名称都与枚举值名称匹配,则可以通过反射来完成。 –

+0

你可以通过追加'()'来运行一个动作,不需要执行'.Invoke()'。只是一个fyi – vrwim

+0

@Jon Skeet也许词典的工作正常,但添加一切听起来不太好。尽管如此,还是比一个巨大的开关更好。使每个枚举名称匹配每个枚举名称听起来有点危险添加新东西 – null

回答

3

不能说我会推荐这样做,但:

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

然后你只需要调用Functions.Add(1,1)

如果你真的使用一个枚举它,那么你可以这样做:

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

然后Functions.Execute(Functions.Function.Add)(额外的功能是因为我的枚举是在函数类中)。

+0

这看起来很有趣,但是这会在被多次调用时影响性能吗?另外为什么'.Invoke(null,null);'? – null

+0

我测试了这个,性能影响非常大,如果我输入name函数作为字符串,并且x133如果我执行'.ToString()'比较常规函数调用,则需要x30次。如果我首先加载methodInfo它需要20倍的时间。 – null

+0

@null'.Invoke(null,null)'调用没有参数的静态方法,你可能需要改变它的东西。使用反射的性能将受到严重影响。我确实说过我建议你不要。如果你觉得你需要反思,那么你是否应该以正确的方式进行研究可能是值得的。我只能回答你的问题,因为我不知道你在努力完成什么。所有这一切,表现的惩罚可能是可以接受的,这取决于你的情况。不要过早优化。 –

0

如果你的函数包含相同signature那么你可以做这样的事情

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


} 
+0

我试图避免开关,这是第一个问题。如果我有很多功能,代码会太长。 – null