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