2016-08-19 8 views
1

私がenumた内容に応じて機能を実行する必要があり、これよりもそれに別の方法がある場合、私は思ったんだけどプログラムがあります。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行に変身することができます。しかし、これは可能ではありません。数値型だけがenumとして受け入れられます。 アクションのList<T>があると思われますが、実行時に各アクションをリストに追加する必要があります。

編集: ソースコードでこれが行われていますが、実際には理解できません。これは私が得るものです: 彼らはstring(メソッド名)と、彼らは法に含むカスタムAttribute作成します。その後、私はこれはそれの名前で呼ばれているのか分からない

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

を、私は私はこれについての情報を見つける方法を知りません。

EDIT2:私がこれをやりたいと思った方法を見つけたら、関数を使ってインターフェイスを追加し、関数内のコードでそのインターフェイスを実装し、Dictionary<Enum, Interface>を使って呼び出します。私は知らない私は自分の質問に答える必要があれば、とにかく皆のおかげで誰かが私を助けました。

+4

ような何かを行うことができます実行時にメソッド名がすべてenum値の名前と一致する場合は、それを反映させることもできます。 –

+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)(余分な機能は、私の列挙体が関数クラスの中にあったためです)。あなたの関数が同じsignatureが含まれている場合は

+0

これは面白そうですが、これは何度も呼び出されるとパフォーマンスに影響しますか?また、なぜ '.Invoke(null、null);'? – null

+0

これをテストしたところ、パフォーマンスの影響はかなり大きかったです。名前関数を文字列として入力するとx30時間、通常の関数呼び出しと比較して '.ToString()'を実行するとx133がかかります。最初にmethodInfoをロードするとx20時間かかります。 – null

+0

@null '.Invoke(null、null)' argを持たない静的メソッドを呼び出すには、あなたのためにそれを変更する必要があります。リフレクションを使用したパフォーマンスには大きな影響があります。私はあなたがそうしないと言ったと言いました。それはあなたがあなたがリフレクションを必要と感じる場合は、それを正しい方法を行っているかどうかを検討する価値があるかもしれません。あなたが達成しようとしていることがわからないので、私はあなたの質問に答えることができます。あなたの状況に応じて、パフォーマンスペナルティが受け入れられる可能性があります。途中で最適化しないでください。 –

0

することはあなたがさてあなたは `辞書 `を持っている可能性が...しかし、再び、あなたはそれを構築する必要があると思います。この

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

関連する問題