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");
}
}
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);
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With