Reputation: 589
I have two generic method overloads, that differ by the number of generic type parameters and argument type
// Argument types
public class Bar<T> {}
public class Bar<T, U> {}
// Generic method overloads
private static void Foo<T> (Bar<T> b) {}
private static void Foo<T, U> (Bar<T, U> b) {}
I'm assuming that i can get the method info for either one by using the appropriate number of type parameters
BindingFlags Flags = BindingFlags.NonPublic | BindingFlags.Static;
// Should give Foo<int>
GetType ().GetMethod ("Foo", Flags).MakeGenericMethod (typeof(int));
// Should give Foo<int, int>
GetType ().GetMethod ("Foo", Flags | BindingFlags.Static).MakeGenericMethod (typeof(int), typeof(int));
However this fails with System.Reflection.AmbiguousMatchException.
I tried specifying things like new Type[] {typeof (Bar<,>)}
as the types
argument for some of the GetMethod
overloads
, but the result was always null. I know i can workaround the ambiguity simply by using different names for the functions, but i'm interested to know if there's an actual solution to this.
I'm on .NET standard 2.0, .NET Core 2.0
Upvotes: 2
Views: 1602
Reputation: 142203
If you don't want to use Type.GetMethods
and iterate over the results you can use this overload of GetMethod
and Type.MakeGenericMethodParameter
which is available from .NET Core 2.1:
class MyClass
{
// Argument types
public class Bar<T> { }
public class Bar<T, U> { }
// Generic method overrides
private static void Foo<T>(Bar<T> b) { }
private static void Foo<T, U>(Bar<T, U> b) { }
}
typeof(MyClass)
.GetMethod(
"Foo",
1,
BindingFlags.NonPublic | BindingFlags.Static,
null,
new[] { Type.MakeGenericSignatureType(typeof(MyClass.Bar<>), Type.MakeGenericMethodParameter(0)) },
null
); // First Foo
typeof(MyClass)
.GetMethod(
"Foo",
2,
BindingFlags.NonPublic | BindingFlags.Static,
null,
new[] { Type.MakeGenericSignatureType(typeof(MyClass.Bar<,>), Type.MakeGenericMethodParameter(0),Type.MakeGenericMethodParameter(1)) },
null
); // Second Foo
UPD
Since Type.MakeGenericMethodParameter
is not available for you the only option I see (if every method is not a part of generic class with the same generic type arguments) is to use GetMethods
and filter the results. Simplest filter in this case would be number of generic parameters;
var secondMethod = typeof(MyClass).GetMethods(BindingFlags.NonPublic | BindingFlags.Static)
.Where(mi => mi.Name == "Foo" && mi.GetGenericArguments().Length == 2)
.First();
Upvotes: 4