C# 联合查询_《C# in Depth》之LINQ中的流与延迟执行

在《C# in Depth》的第11章,作者花了大量篇幅深入介绍了LINQ to Objects的相关知识,包括LINQ的基本概念、查询语句中的类型转换、筛选与排序、Join、Grouping等。但是坦白说,我认为本章大部分内容仍然属于“语法指导”的范畴,这些都可以通过阅读微软官方文档获取,所以还是略有点失望的。本章对于我来说最值得写下来的是对“流与延迟执行”(streaming and deferred execution)的概念的介绍,因为这个是我知识点的空白。

流与延迟执行

直接用书中的例子来说明,加入有如下查询语句:

var 

我们要从一个Person类型的集合里取出所有Age属性大于18的成员的Name属性的集合。这段语句执行时,并不会从数据源加载整个集合,而是以流的形式逐个成员加载,下图是作者画出的这段语句的时序图。

6bc15ce7c1f0ed40b8fa7eae3a6d8de5.png

执行代码时,程序会每次取出一个成员来执行查询,如果这个成员符合Age≥18的条件,则将它的Name属性“select出来”,存入“结果集合”中,然后再取出下一个成员,依次执行。这就是延迟执行(deferred execution)的概念。

延迟执行可以有效的减少内存消耗以及提高性能,避免将集合一次性整个加载到内存中。但是,并不是所有的LINQ语句都具有延迟执行的特性,例如Enumerable.Reverse方法要求将集合元素的排序反转,就要求必须将整个集合加载到内存中再执行后面的操作,它就无法延迟执行,只能“缓存操作”(buffering operation)。

流和延迟操作的概念,对于程序设计也是很有参考意义的,有条件的情况下,我们应该尽量设计“流”式操作,而不是“缓存”式操作。

LINQ查询与普通方法的选择

我们知道,LINQ查询表达式实际上类似一种语法糖,它在编译时会被翻译成普通C#语句。例如,上面的例子中的LINQ语句会翻译成以Lambda表达式为参数的扩展方法形式:

// LINQ查询表达式

因此,在实际使用中完全可以用Lambda表达式替代LINQ,一个C#程序组即使完全不用到LINQ也是很正常的事情。对于我来说,我认为在大多数情况下Lambda表达式的写法更加优雅达意,所以我也没怎么用过LINQ。

那么什么时候LINQ比Lambda更好用呢?作者认为,在需要用到匿名类型作为查询的中间载体时,以及涉及到多表达式联合查询(join)时,LINQ具有更简单的写法和更好的可读性。书中有例子,我就不再搬运了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值