LINQ中的"延迟查询"特性
很多标准查询操作符的设计原型都是返回一个IEnumerable<T>类型的序列, 这些标准查询操作实际上不会在代码执行到那一行的时候就返回一个序列, 事实上返回的是一个对象. 当在枚举(比如foreach)这个对象的时候会从IEnumerable<T>序列中生成一个元素, 这个时候才会真正执行查询操作. 这就是所谓的"延迟查询".
小例子证明"延迟查询"的存在性
1 2 3 4 5 6 7 8 9 10 | int [] intArray = new int [] { 0, 1, 2, 3 }; IEnumerable< int > items = intArray.Select(i => i); //返回i //输出结果 foreach ( int item in items) Console.WriteLine(item); //更改一下intArray中的某个元素, 再进行"输出结果" intArray[0] = 4; Console.WriteLine( "改变intArray第一个元素值之后的输出结果:" ); //再次输出结果 foreach ( int item in items) Console.WriteLine(item); |
两次输出结果分别为:0, 1, 2, 3 和 4, 1, 2, 3. 由此可见只有在枚举items的时候才会真正的执行查询操作. 如果没有延迟查询, 两次输出的结果应该是相同的.
避免"延迟查询"的方法
可以使用一个不返回IEnumerable<T>数据类型的转换操作符, 如ToArray, ToList, ToDictionary或ToLookup, 这样查询操作就不会被延迟了. 同样是上面例子的, 通过ToList操作符返回一个List<int>型序列, 就不会产生"延迟查询"的现象:
1 2 3 4 5 6 7 8 9 10 | int [] intArray = new int [] { 0, 1, 2, 3 }; List< int > items = intArray.Select(i => i).ToList(); //加了ToList操作符 //输出结果 foreach ( int item in items) Console.WriteLine(item); //更改一下intArray中的某个元素, 再进行"输出结果" intArray[0] = 4; Console.WriteLine( "改变intArray第一个元素值之后的输出结果:" ); //再次输出结果 foreach ( int item in items) Console.WriteLine(item); |
这样两次输出的结果就都为0, 1, 2, 3了.
"延迟查询"可能导致的错误
因为有了延迟, 被枚举的时候才会真正的去执行一个查询, 因此如果程序编译通过了但绝对不意味着这个查询就是没事儿的. 比如查询一个字符串数组里面, 每个元素的第3个字符是什么的时候, 如果某个字符串长度<3, 那么在运行的时候就会报错, 而程序在编译的时候是没有问题的.
作者:Create Chen
出处:http://technology.cnblogs.com
说明:文章为作者平时里的思考和练习,可能有不当之处,请博客园的园友们多提宝贵意见。
本作品采用知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架