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

发布于 2024-12-06 10:09:05 字数 906 浏览 4 评论 0原文

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[])?

请帮助我修好它!

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

执手闯天涯 2024-12-13 10:09:05

仅使用 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,因为它已经包含 WhereMethodInfo 定义。

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>.

手心的海 2024-12-13 10:09:05

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

这是获取任何通用方法的更通用方法通过扩展方法,使用干净的语法,如下所示:

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

注意 Refl.T1 取代了泛型类型参数。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文