2011-08-03 19 views
0

C#プログラムの入力がメソッド呼び出しを制御できるようにするにはどうすればよいですか?たとえば:c#入力に基づいてメソッド呼び出しを指定しますか?

たちはデリゲート型を持っていると仮定します

delegate void WriteMe(); 

とメソッドのカップル:

void PrintInt() { Console.WriteLine(10); } 
void PrintString() { Console.WriteLine("Hello world."); } 

、入力が起動順序を選択することができます:

public static WriteMe ProcessInvocationInput(int[] val) { 
    WriteMe d = null; 
    foreach (int i in val) { 
     switch (i) { 
      case 1: d += PrintInt; break; 
      case 2: d += PrintString; break; 
     } 
    } 
} 

それをすべて呼び出すコード:

static void Main(string args[]) { 
    int[] values = {1, 2, 3}; // Obviously this array could be filled 
           // from actual input (args, file, wherever) 
    WriteMe d = ProcessInvocationInput(values); 

    d(); 
} 

私はこの質問を投稿している理由は、単純な考えのように見えるものを実装するのはむしろ複雑だからです。私はこの動作を達成するための別の方法がリフレクションAPIであることを知っていますが、それはさらに複雑です。本当にあなたがカバーしようとしている範囲に依存

+0

あなたは計画を立てていますか型に基づいて、または値に基づいてメソッドをosing? –

+0

(ProcessInvocationInputに与えられたint []の私の例では)値に基づいています。 – jdphenix

+0

コードが動作します。あなたの質問は何ですか? – svick

答えて

2

。あなたはスイッチを使用することができ、単純なケースでは(私はお勧めしたいと列挙型は、それを明確にするために):

enum InputCommands 
{ 
    PrintHelloWorld = 1, 
    ExecuteFixedBinary = 2, 
    ... 
} 

switch((InputCommands)inputInt) 
{ 
    case InputCommands.PrintHelloWorld: ... 
    case InputCommands.ExecuteFixedBinary: ... 
} 

をしかし、あなたは、シェルを書いている場合は、IExecutableCommandインターフェースのいくつかの並べ替えのような、より堅牢なものを、必要とするよりも、さまざまなクラスによって実装されています。

interface IExecutableCommand 
{ 
    void Execute(string arg); 
} 

複数の呼び出し要求を処理し、より複雑な引数を処理するには、いくつかのパーサーを実装する必要があります。

Reflectionを使用する場合は、入力内容を確認してください。これは、カスタム属性を持つメソッドを実行するだけで実行できます。

class ExecutableMethodAttribute : Attribute { } 

[ExecutableMethod] 
void Foo() 
{ 
    ... 
} 

この属性を持つメソッドをフィルタリングするのは簡単です:あなたがアクションに値の辞書を作成する場合は、

private static Dictionary<int,Action> _actions=new Dictionary<int,Actions> { 
    {1, PrintInt}, 
    {2, PrintString}, 
}; 

を行うことができます

someAssembly.GetTypes() 
    .SelectMany(t => t.GetMethods()) 
    .Where(mi => mi.GetCustomAttributes(typeof(ExecutableMethodAttribute), true).Any()) 
+0

ありがとう、これは私が知る必要があることを正確に教えてくれます。 – jdphenix

0
public static ICollection<Action> ProcessInvocationInput(int[] val) 
{ 
    var actions = new List<Action>(); 
    foreach (int i in val) 
    { 
     switch (i) 
     { 
      case 1: actions.Add(PrintInt); 
      case 2: actions.Add(PrintString); 
     } 
    } 

    return actions; 
} 

... 
foreach (var action in ProcessInvocationInput(input)) 
{ 
    action(); 
} 
0

次に、あなただけのループと処理することができます

foreach (var item in input) _actions[item](); 
関連する問題