2011-06-24 23 views
16

私のアプリケーションには、各ジョブに呼び出す必要があるメソッドのリストとパラメータがあります。基本的に次のオブジェクトを含むリストが呼び出されます。C#で名前を使用してメソッドを呼び出す

string Name; 
List<object> Parameters; 

だから、基本的に、仕事は私はこのリストを列挙したい実行され、関連するメソッドを呼び出すとき。

TestMethod(string param1, int param2) 

私のメソッドオブジェクトは、次のようになります::

Name = TestMethod 
Parameters = "astring", 3 

はこれを行うことが可能ですか?例えば、私は次のようなメソッドを持っている場合私はここでリフレクションが鍵になると思います。

答えて

35

確かに、あなたはこのようにそれを行うことができます。

public class Test 
{ 
    public void Hello(string s) { Console.WriteLine("hello " + s); } 
} 

... 

{ 
    Test t = new Test(); 
    typeof(Test).GetMethod("Hello").Invoke(t, new[] { "world" }); 

    // alternative if you don't know the type of the object: 
    t.GetType().GetMethod("Hello").Invoke(t, new[] { "world" }); 
} 

呼び出しの2番目のパラメータは、()あなたのメソッドに渡すすべてのパラメータを含むオブジェクトの配列です。

public void InvokeMethod(string methodName, List<object> args) 
{ 
    GetType().GetMethod(methodName).Invoke(this, args.ToArray()); 
} 
+0

ファンタスティック、まさに私が探しています。ありがとう:) – Chris

1

.NET Framework 4を使用している場合は、dynamicを参照してください。それ以外の場合はGetMethodとし、InvokeMethodInfoとします。

+0

私は悲しいことではありません、私は3.5になります – Chris

0

使用MethodBase.Invoke():すべてが同じクラスに属するメソッドを想定し

は、次のような、そのクラスの何かの方法を持つことができます。 System.Reflectionで.NET 2.0に対応する必要があります。

-1

リフレクションに頼らざるを得ない場合は、おそらくあなたのタスクを達成するためのより良い方法があります。それはもう少しアーキテクチャを取るかもしれませんが、それは実行可能です。

特に、コードの可読性と管理性を向上させる場合、コードを増やすことは悪いことではありません。ほとんどの場合、リフレクションを理解することは難しく、コンパイル時の型の安全性をほとんど失うことになります。あなたの例では、おそらくスイッチステートメントと呼び出す予定のメソッドごとに別個のオブジェクトを手に入れることができます。例えば

// Have some object hold the type of method it plans on calling. 
enum methodNames 
{ 
    Method1, 
    Method2 
} 

... 
class someObject 
{ 
    internal methodNames methodName {get; set;} 
    internal object[] myParams; 
} 
... 

// Execute your object based on the enumeration value it references. 
switch(someObject1.methodName) 
{ 
    case Method1: 
     Test.Method1(Int32.Parse(someObject1.myParams[0].ToString),someObject1.myParams[1].ToString()); 
     break; 
    ... 
} 

あなたが唯一の理由だけで、事前に自分自身を設定していない、呼び出すメソッドの可能性の明確なセットを持っていることがわかっている場合は?

1

NuGet to the rescue! PM> Install-Package dnpextensions

プロジェクトにそのパッケージが含まれていると、すべてのオブジェクトは.InvokeMethod()という拡張子になり、メソッド名は文字列と任意の数のパラメータになります。

あなたはメソッド辞書を強く入力したい場合、あなたはタイプMETHODINFOのキーを作成し、このようにそれらを得ることができるので、技術的には、メソッド名のための「魔法の文字列を」使用しない

...

MethodInfo[] methodInfos = typeof(MyClass).GetMethods(); 

そして、あなたはこのような何か...

var methods = new Dictionary<MethodInfo, Object[]>(); 
foreach (var item in methods) 
    item.key.Invoke(null, item.value); 
    // 'null' may need to be an instance of the object that 
    // you are calling methods on if these are not static methods. 

を行うことができますそれとも、私が先に述べたdnpextensionsを使用して上記のブロックのいくつかのバリエーションを行うことができます。

関連する問題