24

Assuming there exist a class X as described below, how do I get method information for the non-generic method? The code below will throw an exception.

using System; class Program { static void Main(string[] args) { var mi = Type.GetType("X").GetMethod("Y"); // Ambiguous match found. Console.WriteLine(mi.ToString()); } } class X { public void Y() { Console.WriteLine("I want this one"); } public void Y<T>() { Console.WriteLine("Not this one"); } } 

2 Answers 2

36

Don't use GetMethod, use GetMethods, then check IsGenericMethod.

using System; using System.Linq; class Program { static void Main(string[] args) { var mi = Type.GetType("X").GetMethods().Where(method => method.Name == "Y"); Console.WriteLine(mi.First().Name + " generic? " + mi.First().IsGenericMethod); Console.WriteLine(mi.Last().Name + " generic? " + mi.Last().IsGenericMethod); } } class X { public void Y() { Console.WriteLine("I want this one"); } public void Y<T>() { Console.WriteLine("Not this one"); } } 

As a bonus - an extension method:

public static class TypeExtensions { public static MethodInfo GetMethod(this Type type, string name, bool generic) { if (type == null) { throw new ArgumentNullException("type"); } if (String.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); } return type.GetMethods() .FirstOrDefault(method => method.Name == name & method.IsGenericMethod == generic); } } 

Then just:

static void Main(string[] args) { MethodInfo generic = Type.GetType("X").GetMethod("Y", true); MethodInfo nonGeneric = Type.GetType("X").GetMethod("Y", false); } 
Sign up to request clarification or add additional context in comments.

1 Comment

I'm surprised this isn't part of .NET by default.
1

Based on the answer of Konrad Morawski, I have created an enhanced extension method:

public static MethodInfo GetMethod (this Type i_oContainingType, string i_sMethodName, BindingFlags i_enBindingFlags, Type[] i_aoArgumentType, bool i_bGeneric) { if (i_oContainingType == null) throw new ArgumentNullException (nameof (i_oContainingType)); var aoMethod = i_oContainingType.GetMethods (i_enBindingFlags); var listoMethod = new List<MethodInfo> (); foreach (var oMethod in aoMethod) { if (!string.Equals (oMethod.Name, i_sMethodName)) continue; if (oMethod.IsGenericMethod != i_bGeneric) continue; var aoParameter = oMethod.GetParameters (); if (aoParameter.Length != i_aoArgumentType?.Length) continue; int iParamMatch = 0; for (int ixParam = 0; ixParam < aoParameter.Length; ixParam++) { if (aoParameter[ixParam].ParameterType == i_aoArgumentType[ixParam]) iParamMatch++; } if (iParamMatch != aoParameter.Length) continue; listoMethod.Add (oMethod); } if (listoMethod.Count != 1) { string sError = "Method with Name '" + i_sMethodName + "' and BindingFlags '" + i_enBindingFlags + "' and Parameter Types '" + i_aoArgumentType?.ToString ("', '") + "'"; if (listoMethod.Count == 0) throw new MissingMethodException (sError + " has no match."); else throw new AmbiguousMatchException (sError + " has " + listoMethod.Count + " matches."); } return listoMethod[0]; } public static MethodInfo GetPrivateInstanceMethod (this Type i_oContainingType, string i_sMethodName, Type[] i_aoArgumentType, bool i_bGeneric) { return GetMethod (i_oContainingType, i_sMethodName, BindingFlags.NonPublic | BindingFlags.Instance, i_aoArgumentType, i_bGeneric); } public static MethodInfo GetPublicInstanceMethod (this Type i_oContainingType, string i_sMethodName, Type[] i_aoArgumentType, bool i_bGeneric) { return GetMethod (i_oContainingType, i_sMethodName, BindingFlags.Public | BindingFlags.Instance, i_aoArgumentType, i_bGeneric); } 

Notice:
i_aoArgumentType.ToString (..) is another extension method. I think you could guess what it does.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.