【问题标题】:How is 'from/where/select' keywords impemented under the hood in LINQ and C#?'from/where/select' 关键字是如何在 LINQ 和 C# 的底层实现的?
【发布时间】:2008-10-10 11:45:54
【问题描述】:

当我在导入System.Linq namespace 后键入'from'(在LINQ 查询中)时,它被理解为关键字。这种魔法是如何发生的?

'from' 是某种类型的扩展方法吗?

【问题讨论】:

    标签: c# .net linq


    【解决方案1】:

    实际上,是的 - LINQ 关键字映射到扩展方法。但实际上,它更有趣;从字面上看,就好像编译器直接替换了一些关键方法,即

    var qry = from cust in db.Customers
              where cust.IsActive
              select cust;
    

    变成:

    var qry = db.Customers.Where(cust => cust.IsActive);
    

    (如果我们有一个重要的选择,它会添加 .Select(...some projection...)

    不同的 LINQ 关键字映射到不同的方法 - 即有 OrderBy、GroupBy、ThenBy、OrderByDescending 等。

    IEnumerable<T>/IQueryable<T> 的情况下,然后通过扩展方法解决这些问题(通常由 Enumerable/Queryable 提供)- 但是,如果您的可查询对象声明了自己的 Where/OrderBy/etc,那么这些会被优先使用。

    Jon Skeet 在C# in Depth 的后半部分对此进行了更多介绍。我还看到了an example of Jon's,他在其中讨论了一些非常奇怪的含义——比如在一个类型上调用静态方法。

    【讨论】:

    • 省略 Select() 只是一种优化。即使调用 Select(x=>x); 它仍然需要 Select()
    • 是的,但它确实是一种优化。如果您有“var qry = from x in y select x”,它将保留 Select - 即变为“var qry = y.Select(x=>x)” - 但是,在许多其他典型的简单情况下,它将省略它(除非你有一个重要的投影)。
    【解决方案2】:

    Marc Gravell 有answered the question admirably,但我无法抗拒提及weird things you can do with query expressions 的诱惑。编译器真的不太关心它是如何找到“Select”成员或“Where”等的。

    编译器在进行正常编译之前将代码翻译成“没有查询表达式的 C# 3.0”的方式真的很漂亮——这是一种将新功能引入语言的绝妙方式,但只对规范的一个孤立部分产生影响.

    【讨论】:

    • 已经在 ;-p 中链接了它(我只需要几秒钟就可以找到它......)
    • “你的友好标签团队 MVP” ;-p
    【解决方案3】:

    “from”是一个语言关键字(就像“if”或“foreach”一样)。

    您甚至不需要导入 System.Linq 即可使用“from”,但您需要使用 3.5 框架。

    【讨论】:

    • 你甚至不需要 3.5 框架——你只需要一套合适的方法。例如,LINQBridge 适用于 .NET 2.0,您可以针对它编写 C# 3.0。
    • 不,你没有。您需要 C# 3.0,这不是一回事。例如,LINQBridge 通过 C# 3.0 将 LINQ-to-Objects 引入 .NET 2.0。
    • "from" 不是语言关键字。它是一个依赖于上下文的语法元素。当您意识到可以将变量命名为“from”(不带@),但不能将变量命名为“if”或“foreach”(除非添加@)时,区别就变得很明显了。
    猜你喜欢
    • 2018-10-23
    • 2010-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-15
    • 2013-09-03
    • 1970-01-01
    • 2020-02-20
    相关资源
    最近更新 更多