Get only methods with a specific signature from Type.GetMethods ()

I want to list all type methods with a specific method signature.

For example, if the type has several public methods: public void meth1 (int i); public void meth2 (int i, string s); public void meth3 (int i, string s); public int meth4 (int i, string s);

I want to list all the methods that expect int first and a string as the second parameter, and will return void.

How can i do this?

+7
source share
5 answers

You can use something like this:

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

And use it as follows:

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

You will need to check all MethodInfo yourself. MethodInfo.GetParameters() calling MethodInfo.GetParameters() , you get a collection of ParameterInfo objects, which in turn have the ParameterType property.

Same thing for the return type: check the ReturnType MethodInfo property.

+4
source

Given this class:

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

You can use the Reflection and LINQ bits:

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

or other syntax (which in this case is really nicer)

 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; 

Test:

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

Output:

 M2 M3 
+1
source

This is an extension method to use EvgK's enhanced response.

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

Use it like

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

All Articles