2009-06-02 4 views
25

私は、クラスのメソッドを検査し、特定のシグネチャに一致するものを含むドロップダウンリストを作成しました。問題は、選択された項目をリストから取得し、デリゲートがそのメソッドをクラス内で呼び出すようにすることです。最初の方法は機能しますが、私は2番目の方法の一部を理解できません。例えばmethodinfoからデリゲートを取得する

public delegate void MyDelegate(MyState state); 

public static MyDelegate GetMyDelegateFromString(string methodName) 
{ 
    switch (methodName) 
    { 
     case "CallMethodOne": 
      return MyFunctionsClass.CallMethodOne; 
     case "CallMethodTwo": 
      return MyFunctionsClass.CallMethodTwo; 
     default: 
      return MyFunctionsClass.CallMethodOne; 
    } 
} 

public static MyDelegate GetMyDelegateFromStringReflection(string methodName) 
{ 
    MyDelegate function = MyFunctionsClass.CallMethodOne; 

    Type inf = typeof(MyFunctionsClass); 
    foreach (var method in inf.GetMethods()) 
    { 
     if (method.Name == methodName) 
     { 
      //function = method; 
      //how do I get the function to call? 
     } 
    } 

    return function; 
} 

はどのようにして第二の方法のコメントアウト部分が動作するのですか? MethodInfoをデリゲートにキャストするにはどうすればよいですか?

ありがとうございます!

編集:これは実際の解決策です。

public static MyDelegate GetMyDelegateFromStringReflection(string methodName) 
{ 
    MyDelegate function = MyFunctionsClass.CallMethodOne; 

    Type inf = typeof(MyFunctionsClass); 
    foreach (var method in inf.GetMethods()) 
    { 
     if (method.Name == methodName) 
     { 
      function = (MyDelegate)Delegate.CreateDelegate(typeof(MyDelegate), method); 
     } 
    } 

    return function; 
} 

答えて

21

あなたは、問題のメソッドが静的またはインスタンスメソッドであるかどうかに応じて、Delegate.CreateDelegate()のいくつかのフォームを呼び出す必要があります。

+1

ありがとうございましたnkohari、私が必要とするように正確に働いた。 –

8
private static Delegate CreateDelegate(this MethodInfo methodInfo, object target) { 
    Func<Type[], Type> getType; 
    var isAction = methodInfo.ReturnType.Equals((typeof(void))); 
    var types = methodInfo.GetParameters().Select(p => p.ParameterType); 

    if (isAction) { 
     getType = Expression.GetActionType; 
    } 
    else { 
     getType = Expression.GetFuncType; 
     types = types.Concat(new[] { methodInfo.ReturnType }); 
    } 

    if (methodInfo.IsStatic) { 
     return Delegate.CreateDelegate(getType(types.ToArray()), methodInfo); 
    } 

    return Delegate.CreateDelegate(getType(types.ToArray()), target, methodInfo.Name); 
} 
+0

これは受け入れられた答えでなければなりません:それは直接質問を解決します – Graviton

+1

@Gravitonメソッド署名を 'Delegate'型として持つかどうかによって異なります。この場合、OPは彼が「MyDelegate」を前もって仮定できることを示しているようである。この場合、NateとOPが組み入れた解決策が最良である。一方、これは、*その他の*質問に対する優れた答えです。これは、適切な 'Delegate'型へのアクセスがない場合(つまり、典型的には' MethodInfo'を取得したものです)名前だけでは青)...デリゲートを作成するには、そのようなデリゲートタイプが必要です(.NETの鶏肉と卵の問題)。 –

関連する問題