2016-05-12 17 views
3

上の一般的な方法を見つけ、私はクラス静的クラス

public static class MyClass 
{ 

    public static T MyMethod<T>(T item) where T : ISomeInterface<T>, new 
    { 
     return MyMethod(new[] { item}).First(); 
    } 

    public static IEnumerable<T> MyMethod<T>(params T[] items) where T : ISomeInterface<T>, new 
    { 
     // for simplicity 
     return items.ToList(); 
    } 
} 

と、より複雑なオーバーロードの束を持っています。 は、今私は(私はPowerShellのからの場合呼び出したいので)

public static IEnumerable MyMethod(string typeName, params object[] items) 
    { 
     var type = Type.GetType(typeName, true, true); 
     var paramTypes = new Type[] { type.MakeArrayType() }; 
     var method = typeof(MyClass).GetMethod(
      "MyMethod", BindingFlags.Public | BindingFlags.Static 
       | BindingFlags.IgnoreCase, null, paramTypes, null); 
     return method.Invoke(null, new object[] { items }); 
    } 

を持つクラスを拡張したい。しかしmethodは常にnullです。 GetMethod()経由で私の具体的な方法を得る正しい方法はどれですか。

+1

'table'変数がどのようなものですあなたはまだこのような方法でMakeGenericMethodを呼び出すことによって、閉じたバージョンを作成する必要がありますか?代わりに 'typeName'を意味しますか? –

+0

これらのメソッドのインスタンスメソッドまたは静的メソッドはありますか? –

+0

'静的クラスのインスタンスメンバーを宣言できません '。 –

答えて

2

GetMethodを使用して一般的な方法(私は確信していません)を検索することはできません。ただし、すべてのメソッドを取得し、このようにそれらをフィルタリングするGetMethodsを使用することができます。

var method = typeof (MyClass) 
    .GetMethods(
     BindingFlags.Public | BindingFlags.Static) 
    .Single(x => x.Name == "MyMethod" 
     && x.IsGenericMethod 
     && x.ReturnType == typeof(IEnumerable<>) 
          .MakeGenericType(x.GetGenericArguments()[0])); 

我々は方法を取得しないように、最後の条件は、メソッドの戻り値の型がIEnumerable<T>であることを確認されていることに注意してください代わりにTを返します。

method変数を静的変数としてキャッシュすることができますので、毎回検索する必要はありません。

返されたメソッドはまだ開かれています(これはまだMyMethod<T>です)。

var closed_method = method.MakeGenericMethod(type); 

あなたは、このようにそれを呼び出すことができます:

return (IEnumerable)closed_method.Invoke(null, new object[] { items }); 
+0

私はLINQs Singleメソッドの代わりに、特にこのようなリフレクションコンテキストでLINQs Singleメソッドを使用することをお勧めします。 – thehennyy

+0

@thehennyy、右。同じ基準を持つ複数のメソッドがある場合、失敗したい。 –