【问题标题】:How can I get the MethodInfo of Queryable.Join如何获取 Queryable.Join 的 MethodInfo
【发布时间】:2023-04-03 02:54:01
【问题描述】:

这听起来可能很愚蠢,但我无法获得Queryable.Join(...)MethodInfo。我想得到它是因为How to use a Type variable in a generic method call (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是一个扩展方法,所以方法的第一个参数是this IQueryable&lt;TOuter&gt;。此外,this 的问题非常相似。
  • 哦,是的!谢谢。我去看看。

标签: c# generics reflection iqueryable


【解决方案1】:

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

【讨论】:

  • 这真的很简单!在创建像这样joinMethod.MakeGenericMethod( typeof( TType ), typeof( TType ), JoinKeyType, typeof( TType ) ); result = joinMethod.Invoke( result, new object[] { result, items, OuterKeySelector, InnerKeySelector, ResultSelector } ); 这样的泛型方法后尝试调用该方法时出现另一个错误错误是“不能对 ContainsGenericParameters 为真的类型或方法执行后期绑定操作”。有什么想法吗?
  • @uni - 确保使用MakeGenericMethod 在调用Invoke 时返回的新MethodInfo
  • 我想知道是否在 DLR 中的某个地方还没有所有这些,C# 部分必须有一些东西来解决特定调用站点中调用的MethodInfo。但它可能不会暴露:(
  • 非常感谢。这真的很有帮助!
【解决方案2】:

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

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 方法调用。类型也不重要。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-19
    • 1970-01-01
    相关资源
    最近更新 更多