C#3.0新增功能09 LINQ 基础07 LINQ 中的查询语法和方法语法
介绍性的语言集成查询 (LINQ) 文档中的大多数查询是使用 LINQ 声明性查询语法编写的。但是在编译代码时,查询语法必须转换为针对 .NET 公共语言运行时 (CLR) 的方法调用。 这些方法调用会调用标准查询运算符(名称为 Where
、Select
、GroupBy
、Join
、Max
和 Average
等)。 可以使用方法语法(而不查询语法)来直接调用它们。
查询语法和方法语法在语义上是相同的,但是许多人发现查询语法更简单且更易于阅读。某些查询必须表示为方法调用。 例如,必须使用方法调用表示检索与指定条件匹配的元素数的查询。 还必须对检索源序列中具有最大值的元素的查询使用方法调用。 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>。
为了了解基于方法的查询,我们来仔细讨论它。 在表达式右侧,请注意,where
子句现在表示为 numbers
对象上的实例方法,它具有类型 IEnumerable<int>
(如同你会回忆起的那样)。 如果熟悉泛型 IEnumerable<T> 接口,则会知道它没有 Where
方法。 但是,如果在 Visual Studio IDE 中调用 IntelliSense 完成列表,则不仅会看到 Where
方法,还会看到许多其他方法(如 Select
、SelectMany
、Join
和 Orderby
)。 这些都是标准查询运算符。
虽然看起来似乎 IEnumerable<T> 进行了重新定义以包括这些其他方法,不过实际上情况并非如此。 标准查询运算符作为一种新类型的方法(称为扩展方法 )来实现。 扩展方法可“扩展”现有类型;它们可以如同类型上的实例方法一样进行调用。 标准查询运算符扩展了 IEnumerable<T>,因此可以写入 numbers.Where(...)
。
若要开始使用 LINQ,你在扩展方法方面实际需要了解的所有内容是如何使用正确的 using
指令将它们引入应用程序的范围。 从应用程序的角度来看,扩展方法与常规实例方法是相同的。
有关扩展方法的详细信息,请参阅扩展方法。 有关标准查询运算符的详细信息,请参阅标准查询运算符概述 (C#)。 某些 LINQ 提供程序(如 LINQ to SQL 和 LINQ to XML),会实现自己的标准查询运算符,并为 IEnumerable<T> 之外的其他类型实现额外的扩展方法。
在上面的示例中,请注意,条件表达式 (num % 2 == 0
) 作为内联参数传递给 Where
方法:Where(num => num % 2 == 0).
此内联表达式称为 lambda 表达式。 可采用匿名方法、泛型委托或表达式树的形式编写原本必须以更繁琐的形式编写的代码,这是一种便利的方式。在 C# 中,=>
是 lambda 运算符(读为“转到”)。 运算符左侧的 num
是输入变量,它与查询表达式中的 num
对应。 编译器可以推断出 num
的类型,因为它知道 numbers
是泛型 IEnumerable<T> 类型。 Lambda 的主体与查询语法中或任何其他 C# 表达式或语句中的表达式完全相同;它可以包含方法调用和其他复杂逻辑。 “返回值”就是表达式结果。
若要开始使用 LINQ,不必大量使用 lambda。 但是,某些查询只能采用方法语法进行表示,而其中一些查询需要 lambda 表达式。 进一步熟悉 lambda 之后,你会发现它们是 LINQ 工具箱中一种强大而灵活的工具。 有关详细信息,请参阅 Lambda 表达式。
OrderBy
方法通过对 Where
调用使用点运算符来调用。Where
会生成经过筛选的序列,然后 Orderby
通过进行排序来对该序列进行操作。 由于查询返回 IEnumerable
,因此可通过将方法调用链接在一起在方法语法中撰写查询。 这是当你使用查询语法编写查询时,编译器在幕后进行的工作。 因为查询变量不存储查询的结果,所以可以随时修改它或将它用作新查询的基础(即使在执行过它之后)。成在管理,败在经验;嬴在选择,输在不学! 贵在坚持!
个人作品
BIMFace.SDK.NET
开源地址:https://gitee.com/NAlps/BIMFace.SDK
系列博客:https://www.cnblogs.com/SavionZhang/p/11424431.html
系列视频:https://www.cnblogs.com/SavionZhang/p/14258393.html
技术栈
1、Visual Studio、.NET Core/.NET、MVC、Web API、RESTful API、gRPC、SignalR、Java、Python
2、jQuery、Vue.js、Bootstrap、ElementUI
3、数据库:分库分表、读写分离、SQLServer、MySQL、PostgreSQL、Redis、MongoDB、ElasticSearch、达梦DM
4、架构:DDD、ABP、SpringBoot、jFinal
5、环境:跨平台、Windows、Linux、Nginx
6、移动App:Android、IOS、HarmonyOS、微信小程序、钉钉、uni-app、MAUI
分布式、高并发、云原生、微服务、Docker、CI/CD、DevOps、K8S;Dapr、RabbitMQ、Kafka、RPC、Elasticsearch。
欢迎关注作者头条号 张传宁IT讲堂,获取更多IT文章、视频等优质内容。
出处:www.cnblogs.com/SavionZhang
作者:张传宁 技术顾问、培训讲师、微软MCP、系统架构设计师、系统集成项目管理工程师、科技部创新工程师。
专注于企业级通用开发平台、工作流引擎、自动化项目(代码)生成器、SOA 、DDD、 云原生(Docker、微服务、DevOps、CI/CD);PDF、CAD、BIM 审图等研究与应用。
多次参与电子政务、图书教育、生产制造等企业级大型项目研发与管理工作。
熟悉中小企业软件开发过程:可行调研、需求分析、架构设计、编码测试、实施部署、项目管理。通过技术与管理帮助中小企业实现互联网转型升级全流程解决方案。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
如有问题,可以通过邮件905442693@qq.com联系。共同交流、互相学习。
如果您觉得文章对您有帮助,请点击文章右下角【推荐】。您的鼓励是作者持续创作的最大动力!