我怎样才能得到Queryable.Join的MethodInfo

问题描述:

这可能听起来很愚蠢,但我不能得到 Queryable.Join(...)。我想得到它,因为How to use a Type variable in a generic method call (C#)我怎样才能得到Queryable.Join的MethodInfo

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

我写的东西像

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

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

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

+1

请记住'Queryable.Join'是一个扩展方法,所以方法的第一个参数是'this IQueryable '。另外,[this](http://stackoverflow.com/questions/269578/get-a-generic-method-without-using-getmethods)问题非常相似。 – vcsjones

+0

哦,是的!谢谢。我会看一看。 – uni

使用泛型和反射可能有点乏味。你最好的选择(保持简单)就是使用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 }); 
+0

这真的简化了事情!我在尝试调用方法后出现了另一个错误,例如这种'joinMethod.MakeGenericMethod(typeof(TType),typeof(TType),JoinKeyType,typeof(TType)); \t \t \t \t结果= joinMethod.Invoke(结果,新的对象[] {结果,物品,OuterKeySelector,InnerKeySelector,ResultSelector});'是“后期绑定操作不能在类型或方法针对ContainsGenericParameters是真正执行的错误“.. 有任何想法吗? – uni

+2

@uni - 确保在调用'Invoke'时使用'MakeGenericMethod'返回的新'MethodInfo'。 – vcsjones

+0

我想知道如果DLR中的某个地方已经不是所有这些,那么C#部分必须有一些东西来解析来自特定调用站点的调用的MethodInfo。但它可能不会被曝光:( –

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

​​

很明显,你可以把任何你想在你的表达,只要顶层的东西是你的加入方法调用。类型都不重要。