繁体   English   中英

使用反射调用 Enumerable.Where(或其他重载的泛型方法)

[英]Invoke Enumerable.Where (or other overloaded generic method) using reflection

Enumerable 类中的“Where”方法有 2 个重载(或方法签名):

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);
    }

所以

var where = typeof(Enumerable).GetMethod("Where") 

抛出一个异常,说明一个不明确的匹配,因为,当然,有多个名为“Where”的方法,所以我试图通过参数来区分:

var types = new[] { 
    typeof(IEnumerable<>), 
    typeof(Func<,>)};
var where = typeof(Enumerable).GetMethod("Where", types);

然而,这与任何一个方法签名都不匹配,我不确定为什么。

通用问题:如何通过反射调用重载的泛型方法,而无需迭代类中具有相同名称的所有方法(即,使用 System.Type.GetMethod(System.String, System.Type[])?

请帮我修复它! 谢谢!

仅使用GetMethod()无法完成此操作,因为它具有泛型的局限性。 这就是您正确使用GetMethod()

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);

最好的方法是迭代members因为它已经包含了Where<TSource>两个MethodInfo定义。

您可能有兴趣查看我在另一个答案中发布的代码片段:

这是通过扩展方法获取任何泛型方法的更通用方法,其语法如下所示:

var where = typeof(Enumerable).GetMethod(
  "Where", 
  typeof(IQueryable<Refl.T1>), 
  typeof(Expression<Func<Refl.T1, bool>>
);

请注意代替泛型类型参数的Refl.T1

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM