问题
There are 2 overloads (or method signatures) of the "Where" method in Enumerable class:
namespace System.Linq {
public static class Enumerable {
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate);
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, int, bool> predicate);
}
So
var where = typeof(Enumerable).GetMethod("Where")
throws an exception stating an ambiguous match because, of course, there is more than one method with the name "Where", so I tried to differentiate by the parameters:
var types = new[] {
typeof(IEnumerable<>),
typeof(Func<,>)};
var where = typeof(Enumerable).GetMethod("Where", types);
This however doesn't match either of the method signatures, and I'm not sure why.
Generalized question: How do you invoke an overloaded generic method via reflection without iterating over all the methods in the class w/ the same name (i.e., using System.Type.GetMethod(System.String, System.Type[])?
Please help me fix it! Thanks!
回答1:
You can't accomplish this with only GetMethod()
because it has limitations with generics. This is how you would do it with GetMethod()
properly.
Type enumerableType = typeof(Enumerable);
MemberInfo[] members = enumerableType.GetMember("Where*");
MethodInfo whereDef = (MethodInfo)members[0]; // Where<TSource>(IEnumerable<TSource, Func<TSource,Boolean>)
Type TSource = whereDef.GetGenericArguments()[0]; // TSource is the only generic argument
Type[] types = { typeof(IEnumerable<>).MakeGenericType(TSource), typeof(Func<,>).MakeGenericType(TSource, typeof(Boolean)) };
MethodInfo method = enumerableType.GetMethod("Where", types);
The best way is to just iterate over members
since it already contains both MethodInfo
definitions for Where<TSource>
.
回答2:
You might be interested to see a code snippet I posted in this other answer:
It's a more general way to get any generic method via an extension method, with clean syntax that looks like:
var where = typeof(Enumerable).GetMethod(
"Where",
typeof(IQueryable<Refl.T1>),
typeof(Expression<Func<Refl.T1, bool>>
);
Notice the Refl.T1
that takes the place of a generic type parameter.
来源:https://stackoverflow.com/questions/7538462/invoke-enumerable-where-or-other-overloaded-generic-method-using-reflection