如何获取Queryable.Join的MethodInfo

时间:2011-10-14 15:47:30

标签: c# generics reflection iqueryable

2 个答案:

答案 0 :(得分:5)

使用泛型和反射可能有点单调乏味。您最好的选择(为了简单起见)是使用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,TResult。

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

答案 1 :(得分:1)

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

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方法调用,您就可以在表达式中添加任何内容。类型无关紧要。