代码之家  ›  专栏  ›  技术社区  ›  Daniel Sam

用LINQ编码是如何工作的?幕后发生了什么?

  •  2
  • Daniel Sam  · 技术社区  · 16 年前

    例如:

    m_lottTorqueTools = (From t In m_lottTorqueTools _
                         Where Not t.SlotNumber = toolTuple.SlotNumber _
                         And Not t.StationIndex = toolTuple.StationIndex).ToList
    

    这里发生了什么算法?后台是否有嵌套的for循环?它是否为这些字段构造哈希表?我很好奇。

    3 回复  |  直到 16 年前
        1
  •  6
  •   Jon Skeet    16 年前

    查询表达式通常被转换为扩展方法调用。(他们不 但99.9%的查询使用 IEnumerable<T> IQueryable<T> )

    该方法所做的具体算法因方法而异。示例查询不会使用任何哈希表,但联接或分组操作会使用任何哈希表。

    简单的 Where 调用在c中转换为类似的内容(使用迭代器块,据我所知,目前在vb中还不可用):

     public static IEnumerable<T> Where(this IEnumerable<T> source,
         Func<T, bool> predicate)
     {
         // Argument checking omitted
         foreach (T element in source)
         {
             if (predicate(element))
             {
                 yield return element;
             }
         }
     }
    

    谓词作为委托提供(如果使用 可查询 )对序列中的每个项调用。结果被流式处理,执行被延迟——换句话说,在您开始从结果中请求项目之前,不会发生任何事情,即使这样,为了提供下一个结果,它也只做它需要做的事情。有些运算符不会被延迟(基本上是返回单个值而不是序列的运算符),有些运算符会缓冲输入(例如, Reverse 在返回任何结果之前必须先读取到序列的末尾,因为它读取的最后一个结果是它必须生成的第一个结果)。

    恐怕给出每一个LINQ操作员的详细信息超出了一个答案的范围,但是如果您对具体的问题有疑问,我相信我们会尽力的。

    如果您使用的是Linq to SQL或其他基于 可查询 情况有很大的不同。这个 Queryable 类建立查询(在提供程序的帮助下,它实现 可查询 首先),然后提供者通常将查询转换为更合适的形式(例如SQL)。具体细节(包括缓冲、流等)完全取决于提供商。

        2
  •  1
  •   John Saunders    16 年前

    所发生的不仅取决于方法,还取决于使用中的LINQ提供程序。在这种情况下, IQueryable<T> 返回的是Linq提供程序,它解释表达式树并按自己喜欢的方式处理。

        3
  •  1
  •   Community CDub    7 年前

    LINQ通常有一个 许多 在幕后进行。对于任何查询,首先使用 IQueryableProvider 从那里,查询通常被编译成CIL代码,生成一个指向这个函数的委托,这个函数在调用查询时基本上是使用的。这是一个非常简单的概述-如果你想读一篇关于这个主题的好文章,我建议你看一下 How LINQ Works - Creating Queries . 乔恩·斯基特也在这个网站上发布了一个很好的答案 this question .