C#3.0中的新增功能09 LINQ 基础07 LINQ 中的查询语法和方法语法
介绍性的语言集成查询 (LINQ) 文档中的大多数查询是使用 LINQ 声明性查询语法编写的。但是在编译代码时,查询语法必须转换为针对 .NET 公共语言运行时 (CLR) 的方法调用。?这些方法调用会调用标准查询运算符(名称为? 查询语法和方法语法在语义上是相同的,但是许多人发现查询语法更简单且更易于阅读。某些查询必须表示为方法调用。?例如,必须使用方法调用表示检索与指定条件匹配的元素数的查询。?还必须对检索源序列中具有最大值的元素的查询使用方法调用。?System.Linq命名空间中的标准查询运算符的参考文档通常使用方法语法。?因此,即使在开始编写?LINQ查询时,熟悉如何在查询和查询表达式本身中使用方法语法也十分有用。
下面的示例演示一个简单查询表达式 以及编写为基于方法的查询 的语义上等效的查询。
1 class QueryVMethodSyntax 2 { 3 static void Main() 4 { 5 int[] numbers = { 5,10,8,3,6,12}; 6 7 // 查询语法 8 IEnumerable<int> numQuery1 = 9 from num in numbers 10 where num % 2 == 0 11 orderby num 12 select num; 13 14 // 方法语法 15 IEnumerable<int> numQuery2 = numbers.Where(num => num % 2 == 0).OrderBy(n => n); 16 17 foreach (int i in numQuery1) 18 { 19 Console.Write(i + " "); 20 } 21 Console.WriteLine(System.Environment.NewLine); 22 foreach (int i in numQuery2) 23 { 24 Console.Write(i + " "); 25 } 26 27 // Keep the console open in debug mode. 28 Console.WriteLine(System.Environment.NewLine); 29 Console.WriteLine("Press any key to exit"); 30 Console.ReadKey(); 31 } 32 } 33 /* 34 输出: 35 6 8 10 12 36 6 8 10 12 37 */ 这两个示例的输出是相同的。?可以看到查询变量的类型在两种形式中是相同的:IEnumerable<T>。 为了了解基于方法的查询,我们来仔细讨论它。?在表达式右侧,请注意, 虽然看起来似乎?IEnumerable<T>?进行了重新定义以包括这些其他方法,不过实际上情况并非如此。?标准查询运算符作为一种新类型的方法(称为扩展方法 )来实现。?扩展方法可“扩展”现有类型;它们可以如同类型上的实例方法一样进行调用。?标准查询运算符扩展了?IEnumerable<T>,因此可以写入? 若要开始使用?LINQ,你在扩展方法方面实际需要了解的所有内容是如何使用正确的? 有关扩展方法的详细信息,请参阅扩展方法。?有关标准查询运算符的详细信息,请参阅标准查询运算符概述 (C#)。?某些?LINQ?提供程序(如?LINQ to SQL?和?LINQ to XML),会实现自己的标准查询运算符,并为?IEnumerable<T>?之外的其他类型实现额外的扩展方法。 在上面的示例中,请注意,条件表达式 ( 若要开始使用?LINQ,不必大量使用 lambda。?但是,某些查询只能采用方法语法进行表示,而其中一些查询需要 lambda 表达式。?进一步熟悉 lambda 之后,你会发现它们是?LINQ?工具箱中一种强大而灵活的工具。?有关详细信息,请参阅?Lambda 表达式。
在前面的代码示例中,请注意,
OrderBy ?方法通过对?Where ?调用使用点运算符来调用。Where ?会生成经过筛选的序列,然后?Orderby ?通过进行排序来对该序列进行操作。?由于查询返回?IEnumerable ,因此可通过将方法调用链接在一起在方法语法中撰写查询。?这是当你使用查询语法编写查询时,编译器在幕后进行的工作。?因为查询变量不存储查询的结果,所以可以随时修改它或将它用作新查询的基础(即使在执行过它之后)。
?
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |