Unfortunately System.Reflection doesn't provide a good way to correlate a method on a constructed type with the corresponding method on the generic type definition from which it was constructed. There are two solutions I know of, neither one is perfect:
Solution #1: static TypeBuilder.GetMethod. There's a static version of GetMethod on TypeBuilder that accepts a generic constructed type and a MethodInfo for a method on a generic type definition, and returns the
corresponding method on the specified generic type. In this example, calling TypeBuilder.GetMethod(Foo<int>, Foo<T>.Bar(T))
will give you Foo<int>.Bar(T-as-int)
which you can then use to disambiguate between it and Foo<int>.Bar(int)
.
(The above example will not compile, naturally; I've used Foo<int>
and Foo<T>.Bar(T)
to mean the respective Type and MethodInfo objects which, which are easily obtainable but would make the example too complex).
The bad news is that this only works when the generic type definition is a TypeBuilder, i.e. when you're emitting a generic type.
Solution #2: MetadataToken. It's a little known fact that type members retain their MetadataToken in the transition from generic type definitions to generic constructed types. So in your example, Foo<T>.Bar(T)
and Foo<int>.Bar(T-as-int)
should share the same MetadataToken. That would allow you to do this:
var barWithGenericParameterInfo = typeof(Foo<>).GetMethods()
.Where(mi => mi.Name == "Bar" &&
mi.GetParameters()[0].ParameterType.IsGenericParameter);
var mappedBarInfo = foo.GetType().GetMethods()
.Where(mi => mi.MetadataToken == genericBarInfo.MetadataToken);
(This will not compile either, unless I'm extremely lucky and managed to get it right the first time :) )
The problem with this solution is that MetadataToken wasn't meant for that (probably; the documentation is a little skimpy on that) and it feels like a dirty hack. Nevertheless, it works.