LINQ 如何在内部工作? [英] How LINQ works internally?

查看:37
本文介绍了LINQ 如何在内部工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我喜欢在 .NET 中使用 LINQ,但我想知道它在内部是如何工作的?

I love using LINQ in .NET, but I want to know how that works internally?

推荐答案

询问 LINQ 的特定方面更有意义.否则有点像询问Windows 是如何工作的".

It makes more sense to ask about a particular aspect of LINQ. It's a bit like asking "How Windows works" otherwise.

从 C# 的角度来看,LINQ 的关键部分是为我准备的:

The key parts of LINQ are for me, from a C# perspective:

  • 表达式树.这些是代码作为数据的表示.例如,表达式树可以表示获取一个字符串参数,调用它的 Length 属性,然后返回结果"的概念.这些作为数据而不是作为编译代码存在的事实意味着 LINQ 提供程序(例如 LINQ to SQL)可以分析它们并将它们转换为 SQL.
  • Lambda 表达式.这些是这样的表达:

  • Expression trees. These are representations of code as data. For instance, an expression tree could represent the notion of "take a string parameter, call the Length property on it, and return the result". The fact that these exist as data rather than as compiled code means that LINQ providers such as LINQ to SQL can analyze them and convert them into SQL.
  • Lambda expressions. These are expressions like this:

x => x * 2
(int x, int y) => x * y
() => { Console.WriteLine("Block"); Console.WriteLine("Lambda"); }

Lambda 表达式被转换为委托表达式树.

Lambda expressions are converted either into delegates or expression trees.

匿名类型.这些是这样的表达:

Anonymous types. These are expressions like this:

new { X=10, Y=20 }

这些仍然是静态类型的,只是编译器为你生成了一个不可变的类型,带有 XY 属性.这些通常与 var 一起使用,它允许从其初始化表达式推断局部变量的类型.

These are still statically typed, it's just the compiler generates an immutable type for you with properties X and Y. These are usually used with var which allows the type of a local variable to be inferred from its initialization expression.

查询表达式.这些是这样的表达:

Query expressions. These are expressions like this:

from person in people
where person.Age < 18
select person.Name

这些由 C# 编译器翻译成普通"C# 3.0(即不使用查询表达式的形式).之后应用重载解析等,这对于能够对多种数据类型使用相同的查询语法是绝对关键的,而编译器无需了解诸如 Queryable 之类的类型.上面的表达式将被翻译成:

These are translated by the C# compiler into "normal" C# 3.0 (i.e. a form which doesn't use query expressions). Overload resolution etc is applied afterwards, which is absolutely key to being able to use the same query syntax with multiple data types, without the compiler having any knowledge of types such as Queryable. The above expression would be translated into:

people.Where(person => person.Age < 18)
      .Select(person => person.Name)

  • 扩展方法.这些是静态方法,可以像第一个参数类型的实例方法一样使用.例如,这样的扩展方法:

  • Extension methods. These are static methods which can be used as if they were instance methods of the type of the first parameter. For example, an extension method like this:

    public static int CountAsciiDigits(this string text)
    {
        return text.Count(letter => letter >= '0' && letter <= '9');
    }
    

    然后可以这样使用:

    string foo = "123abc456";
    int count = foo.CountAsciiDigits();
    

    请注意,CountAsciiDigits 的实现使用了另一种扩展方法,Enumerable.Count().

    Note that the implementation of CountAsciiDigits uses another extension method, Enumerable.Count().

    这是大部分相关的语言方面.然后是标准查询运算符的实现,在 LINQ 提供程序中,例如 LINQ to Objects 和 LINQ to SQL 等.//csharpindepth.com/Talks.aspx" rel="noreferrer">"Talks" C# in Depth 网站页面.

    That's most of the relevant language aspects. Then there are the implementations of the standard query operators, in LINQ providers such as LINQ to Objects and LINQ to SQL etc. I have a presentation about how it's reasonably simple to implement LINQ to Objects - it's on the "Talks" page of the C# in Depth web site.

    提供程序(例如 LINQ to SQL)的工作方式通常是通过 Queryable 类.它们的核心是将表达式树转换为其他查询格式,然后使用执行这些进程外查询的结果构建适当的对象.

    The way providers such as LINQ to SQL work is generally via the Queryable class. At their core, they translate expression trees into other query formats, and then construct appropriate objects with the results of executing those out-of-process queries.

    这是否涵盖了您感兴趣的所有内容?如果您还有什么特别想知道的,只需编辑您的问题,我就去看看.

    Does that cover everything you were interested in? If there's anything in particular you still want to know about, just edit your question and I'll have a go.

    这篇关于LINQ 如何在内部工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆