gpt4 book ai didi

linq - Queryable.OfType 如何工作?

转载 作者:行者123 更新时间:2023-12-04 19:23:50 24 4
gpt4 key购买 nike

重要 问题不是“Queryable.OfType 有什么作用,而是“我在那里看到的代码是如何实现的?”

反射(reflection) Queryable.OfType,我看到(经过一些清理):

    public static IQueryable<TResult> OfType<TResult>(this IQueryable source)
{
return (IQueryable<TResult>)source.Provider.CreateQuery(
Expression.Call(
null,
((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(
new Type[] { typeof(TResult) }) ,
new Expression[] { source.Expression }));
}

所以让我看看我是否明白这一点:
  • 使用反射获取对当前方法 (OfType) 的引用。
  • 新建一个方法,一模一样,用MakeGenericMethod把当前方法的类型参数改成呃一模一样的东西。
  • 新方法的参数不是 source 而是 source.Expression。这不是 IQueryable,但我们会将整个内容传递给 Expression.Call,所以没关系。
  • 调用 Expression.Call,传递 null作为方法(奇怪?)实例和克隆的方法作为它的参数。
  • 将该结果传递给 CreateQuery 并转换结果,这似乎是整个事情中最明智的部分。

  • 现在,此方法的效果是返回一个表达式,该表达式告诉提供者省略返回类型不等于 TResult 或其子类型之一的任何值。但是我看不到上面的步骤实际上是如何做到这一点的。它似乎正在创建一个表示返回 IQueryable 的方法的表达式,并使该方法的主体简单地成为整个源表达式,而无需查看类型。是否只是期望 IQueryable 提供程序会默默地不返回任何不是所选类型的记录?

    那么上面的步骤在某种程度上是不正确的,还是我只是没有看到它们如何导致在运行时观察到的行为?

    最佳答案

    它没有通过 null作为方法 - 它将它作为“目标表达式”传入,即它正在调用该方法。这是 null 因为 OfType是一个静态方法,所以它不需要目标。

    调用点 MakeGenericMethodGetCurrentMethod()返回开放版本,即 OfType<>而不是 OfType<YourType> .
    Queryable.OfType本身并不意味着包含任何省略返回任何值的逻辑。这取决于 LINQ 提供程序。 Queryable.OfType点是构建表达式树以包含对 OfType 的调用,以便当 LINQ 提供程序最终必须将其转换为其 native 格式(例如 SQL)时,它知道 OfType被称为。

    就是这样Queryable一般工作 - 基本上它让提供者将整个查询表达式视为表达式树。这就是它的全部目的 - 当提供者被要求将其转换为真正的代码时,这就是魔法发生的地方。
    Queryable不可能自己完成这项工作 - 它不知道提供者代表什么样的数据存储。怎么可能想出OfType的语义不知道数据存储是 SQL、LDAP 还是其他东西?我同意需要一段时间才能让你头脑清醒:)

    关于linq - Queryable.OfType 如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1439992/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com