2011-03-01 8 views
7

特定のメソッドシグネチャを持つ型のすべてのメソッドをリストしたいとします。Get Only Type.GetMethods()の特定のシグネチャを持つメソッド

たとえば、タイプにいくつかのパブリックメソッドがある場合: public void meth1(int i); public void meth2(int i、string s); 公開されているvoid meth3(int i、string s);public int meth4(int i、string s);

intを最初に、文字列を2番目のパラメータとしてすべてのメソッドをリストし、voidを返します。

どうすればいいですか?

答えて

12

EvgKの答えから改善されました。

private static IEnumerable<MethodInfo> GetMethodsBySig(this Type type, 
                   Type returnType, 
                   Type customAttributeType, 
                   bool matchParameterInheritence, 
                   params Type[] parameterTypes) 
     { 
      return type.GetMethods().Where((m) => 
      { 
       if (m.ReturnType != returnType) return false; 

      if ((customAttributeType != null) && (m.GetCustomAttributes(customAttributeType, true).Any() == false)) 
       return false; 

      var parameters = m.GetParameters(); 

      if ((parameterTypes == null || parameterTypes.Length == 0)) 
       return parameters.Length == 0; 

      if (parameters.Length != parameterTypes.Length) 
       return false; 

      for (int i = 0; i < parameterTypes.Length; i++) 
      { 
       if (((parameters[i].ParameterType == parameterTypes[i]) || 
       (matchParameterInheritence && parameterTypes[i].IsAssignableFrom(parameters[i].ParameterType))) == false) 
        return false; 
      } 

      return true; 
     }); 
    } 

var methods = SomeTypeToScan.GetMethodsBySig(
       typeof(SomeReturnType), 
       typeof(SomeSpecialAttributeMarkerType), 
       true, 
       typeof(SomeParameterType)) 
       .ToList(); 
4

ご自身でMethodInfoを調べる必要があります。 MethodInfo.GetParameters()を呼び出すと、オブジェクトのコレクションが得られます。オブジェクトのコレクションはParameterTypeです。

戻り値のタイプと同じ:ReturnTypeプロパティがMethodInfoであることを確認します。

1

このクラスを考える:

public class Foo 
{ 
    public void M1(int i){} 
    public void M2(int i, string s){} 
    public void M3(int i, string s){} 
    public int M4(int i, string s){ return 0; } 
} 

反射とLINQのビットを使用することができる。

Type t = typeof (Foo); 
var theMethods = t.GetMethods().Where(mi => 
          { 
           var p = mi.GetParameters(); 
           if (p.Length != 2) 
            return false; 

           if (p[0].ParameterType != typeof(int) 
            || p[1].ParameterType != typeof(string)) 
            return false; 

           return mi.ReturnType == typeof (void); 
          }); 

または(この場合、実際に進歩して)他の構文

var theMethods = from mi in t.GetMethods() 
        let p = mi.GetParameters() 
        where p.Length == 2 
         && p[0].ParameterType == typeof (int) 
         && p[1].ParameterType == typeof (string) 
         && mi.ReturnType == typeof (void) 
        select mi; 

試験:

foreach (var methodInfo in theMethods) 
{ 
    Console.WriteLine(methodInfo.Name); 
} 

出力:

public static class Extensions 
{ 
    public static IEnumerable<MethodInfo> GetMethodsBySig(this Type type, Type returnType, params Type[] parameterTypes) 
    { 
     return type.GetMethods().Where((m) => 
     { 
      if (m.ReturnType != returnType) return false; 
      var parameters = m.GetParameters(); 
      if ((parameterTypes == null || parameterTypes.Length == 0)) 
       return parameters.Length == 0; 
      if (parameters.Length != parameterTypes.Length) 
       return false; 
      for (int i = 0; i < parameterTypes.Length; i++) 
      { 
       if (parameters[i].ParameterType != parameterTypes[i]) 
        return false; 
      } 
      return true; 
     }); 
    } 
} 

そして、このようにそれを使用します:

var methods = this.GetType().GetMethodsBySig(typeof(void), typeof(int), typeof(string)); 
6
type.GetMethods().Where(p => 
       p.GetParameters().Select(q => q.ParameterType).SequenceEqual(new Type[] { typeof(int), typeof(string) }) && 
       p.ReturnType == typeof(void) 
      ); 
+0

小胞体のようにそれを使用して...私の答えは、わずかに異なる構文LINQ、でした。 – Jamiec

+0

ok - more linqified ... lambaとして書くのではなく、シーケンスを等価なものにする...コメントを変更します。 –

0

これは、使用する拡張メソッドであるあなたは、このようなものを使用することができます

M2 
M3 
関連する問題