什么是C#中的System.Linq.Expressions用于?

时间:2009-09-15 13:44:07

标签: c# visual-studio linq abstract-syntax-tree

LINQ是.NET 4.0中的新功能,在.NET 3.5等旧版本中不受支持吗?它有用的是什么?它似乎能够构建表达式树。实际上什么是表达式树? LINQ能够从C#文件中提取类,方法和字段等信息吗?

有人可以为我提供一段代码来演示LINQ可以做什么吗?

7 个答案:

答案 0 :(得分:21)

Linq被添加到.Net 3.5中(并添加到c#3.0编译器以及稍微限制的形式到同一版本中的VB.net编译器)

在语言集成查询中,虽然它涵盖了语言和运行时的许多复杂的添加,以实现这些本身很有用。

表达式功能只是让程序能够在运行时检查传递的某些代码结构的抽象语法。这些被称为lambdas。而且,本质上是一种更容易编写匿名函数的方法,同时使运行时对其结构的内省更容易。

“SQL like”功能Linq最紧密地关联(虽然绝不是唯一的),它被称为Linq to Sql,其中包括:

from f in Foo where s.Blah == "wibble" select f.Wobble;

被编译成该查询的表示,而不是简单地编码执行查询。使它成为linq to sql的部分是将其转换为sql的“后端”。为此,表达式被转换为sql server语句,以执行针对链接数据库的查询,从行到.net对象的映射以及将c#logic转换为等效where子句。如果Foo是普通的.net对象的集合(此时它是“Linq to objects”),那么你可以应用完全相同的代码。表达式的转换将是直接的.Net代码。

上面用语言集成方式编写的lambda实际上相当于:

Foo.Where(f => f.Blah ==“wibble)。选择(f => f.Wobble);

Foo是一个打字的集合。对于数据库,合成类以表示数据库中的值,以允许它进行编译,并允许从sql区域到.net区域的往返值,反之亦然。

Linq的语言集成部分的关键方面是生成的语言结构是结果代码的第一类部分。它们不是简单地产生函数,而是提供构造函数的方式(作为表达式),以便程序的其他方面可以操纵它。

此功能的消费者可能只是选择运行它(执行lambda编译为的函数)或询问描述它的表达式,然后执行与之不同的操作。

使这成为可能的许多方面被置于“Linq”横幅之下,尽管不是Linq themsleves。 例如,匿名类型是易于使用projection(选择可能属性的子集)所必需的,但匿名类型也可以在Linq之外使用。

Linq,特别是通过lambdas(这使得匿名委托在语法方面非常轻量级)导致c#的功能增强。这可以通过IEnumerable<T>上的扩展方法(如Select())加强,对应于许多函数语言中的map和对应于filter的Where()。就像匿名类型一样,这本身并不是“Linq”,虽然被许多人认为是对c#开发的一种强烈有益的影响(这不是普遍的观点,但被广泛认可)。

表达式是一个更高级的主题,对使用 linq完全不了解它们,尽管使用它们可能会有某些“技巧”。 一般情况下,只有在尝试编写linq提供程序时才会关心表达式,这些提供程序是一个代码来获取表达式而不仅仅是一个函数,并使用它来执行除普通函数之外的操作,例如与外部数据源进行对话

其他用途是当你想获得一些关于函数内部正在做什么的元数据时,可能然后编译表达式(产生一个委托,它将允许你将表达式作为一个函数执行)并做一些事情用它或只是查看对象的元数据来做反射代码,编译时间被验证为this answer shows

答案 1 :(得分:4)

这个问题的一个尚未涉及的领域是表达树。关于表达式树(和lambda表达式)有一篇非常好的文章here

提出表达式树的另一个重要的事情是,通过构建表达式树来定义 将要执行的操作,您不必实际做任何事情。我指的是延期执行。

//this code will only build the expression tree
var itemsInStock = from item in warehouse.Items
                   where item.Quantity > 0;

// this code will cause the actual execution
Console.WriteLine("Items in stock: {0}", itemsInStock.Count());

答案 2 :(得分:1)

LINQ是一个.NET 3.5功能,内置语言支持来自C#3.0和Visual Basic 2008.有很多examples on MSDN

答案 3 :(得分:1)

LINQ是在.NET 3.5中引入的。 This site有很多例子。

答案 4 :(得分:1)

这也被广泛涵盖here on SO

答案 5 :(得分:1)

System.Linq.Expressions用于手工构建(或机器生成)表达式树。我有一种感觉,考虑到构建更复杂功能的复杂性,这个命名空间正在使用中。然而它非常强大。例如,我的一个同事最近实现了一个表达式树,它可以使用累积密度函数自动缩放任何LINQ to SQL对象。每个列都有自己的树,它被编译得很快。我一直在构建一个专门的编译器,它广泛地使用它们来实现基本功能,并将生成的其余代码粘合在一起。

请参阅this blog post了解更多信息和想法。

答案 6 :(得分:0)