如何获得queryable.join的MethodInfo

本文关键字:MethodInfo join queryable 何获得 | 更新日期: 2023-09-27 18:11:20

这可能听起来很愚蠢,但我无法获得Queryable.Join(...)MethodInfo。我想得到它,因为如何在泛型方法调用中使用类型变量(c#)

它有2个可用的方法签名,我想获得没有IEqualityComparer的方法签名,所以我需要在GetMethod中指定Type[]

我写了一些像

MethodInfo joinMethod = typeof( Queryable ).GetMethod( "Join", new Type[] { typeof(IEnumerable<>), typeof(Expression<Func<>>), typeof(Expression<Func<>>), typeof(Expression<Func<>>)});

但它不起作用。我不能在上面的泛型中指定类型,因为它们是从外部作为Type传递的(这就是为什么我需要这个反射)。

谁能告诉我怎么做?谢谢!

如何获得queryable.join的MethodInfo

使用泛型和反射可能有点乏味。您最好的选择(为了保持简单)是使用GetMethods并根据您正在寻找的内容进行过滤。

//Overly simplified
MethodInfo joinMethod = typeof(Queryable)
            .GetMethods(BindingFlags.Static | BindingFlags.Public)
            .Where(m => m.Name == "Join" && m.GetParameters().Length == 5)
            .First();

考虑到这一点,此时MethodInfo是不可调用的。您需要使用joinMethod.MakeGenericMethod(/*type array*/)创建它的通用版本。在您的例子中,您需要使用4种类型:TOuter, TInner, TKey, result。

var genericJoinMethod = joinMethod.MakeGenericMethod(new Type[]{your types here});

现在您可以使用genericJoinMethod作为您的期望。

据我所知,这是在编译时不知道类型的唯一方法。

编辑:

考虑到你的评论,我认为它应该是这样的:

MethodInfo joinMethod = typeof(Queryable)
            .GetMethods(BindingFlags.Static | BindingFlags.Public)
            .Where(m => m.Name == "Join" && m.GetParameters().Length == 5)
            .First();
var genericJoinMethod = joinMethod.MakeGenericMethod(typeof(TType), typeof(TType), JoinKeyType, typeof(TType));
result = genericJoinMethod.Invoke( result, new object[] { result, items, OuterKeySelector, InnerKeySelector, ResultSelector } );

在开始实现涉及字符串和参数计数的复杂反射搜索之前,为什么不退一步,让编译器做他更擅长的事情呢?

var fakeExp = (Expression<Func<IQueryable<int>>>)(() => new int[0].AsQueryable().Join(new int[0], x => x, x => x, (x, y) => x));
return ((MethodCallExpression)fakeExp.Body).Method.GetGenericMethodDefinition();

显然,你可以在表达式中放入任何你想要的东西,只要顶层的东西是你的Join方法调用。类型也不重要