2011-03-01 20 views
7

我想列出了具體的方法簽名類型的所有方法的方法。獲取只)特定簽名了Type.GetMethods的(

例如,如果一種類型具有一些公共方法: 公共無效METH1(INT I); public void meth2(int i,string s); public void meth3(int i,string s); public int meth4(int i,string s);

我想列出所有期待一個int作爲第一和一個字符串作爲第二個參數和返回void的方法。

我該怎麼做?

回答

12

您可以使用這樣的事情:

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)); 
4

你必須檢查所有MethodInfoŞ自己。通過撥打MethodInfo.GetParameters(),您將收到一個ParameterInfo對象的集合,這些對象又有一個屬性ParameterType

同樣的返回類型:檢查的MethodInfoReturnType財產。

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); 
} 

輸出:

M2 
M3 
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

好吧 - 更linqified ...使用序列相等,而不是寫作一個蘭巴...我會改變評論。 –

0

這是使用擴展方法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();