调试代码的时候,突然发现Linq语句不会立即执行,当时一头雾水,因此找资料学习了一下,之后发现身边很多人都忽略了这个细节,所以把他拿出来说一下。
一.特点
1:Linq不会立即执行,某些操作才会触发Linq的真正执行,例如 Foreach,Count(),ToList(),ToArray() 等等。
二.问题
1:由于某些操作会触发Linq执行,这样会导致Linq语句的重复执行,这会比较耗费性能,特别像数据库查询这种场景。
三.解决方案
1:为了减少Linq重复执行的问题,先用ToXXX()这类方法转换成集合(例如ToList()),后续的操作就不会触发Linq的执行了。
四.代码
代码只包含三个部分:
1:定义一个类,类名:Patent(专利),重写了ToString()方法
2:定义一个静态类,类名:PatentData(专利数据),包含一个专利数组属性
3:在main方法中演示Linq的使用
- :定义一个patents数组
- :执行Linq代码
- :执行Count()方法
- :执行 ToArray()方法
- :执行 Count()方法
五.代码执行结果
如下图所示:
1.第一步执行Linq代码,并没有真正触发Linq执行
2.第二步执行Count()方法,触发了Linq执行
3.第三步执行 ToArray()方法,也触发了Linq执行
4.第四步执行 Count()方法,没触发了Linq执行
六.原因
1:第一步执行Linq代码,并没有真正触发Linq执行;
因为Where方法返回的结果代表的是一种用于表示计算的抽象数据类型。这个描述有点绕嘴,可以简单的理解为方法定义。如下图,执行完where语句前后patents的内容。
a:执行where之前的patents内容:
b:执行where之后的patents内容:
2:第二步执行Count()方法,触发了Linq执行,第三步执行 ToArray()方法,也触发了Linq执行:
因为Where方法只是方法定义,并没有一个真正的结果集赋值给patents。
3:第四步执行 Count()方法,没触发Linq执行:
因为第三步执行ToArray()方法得到了集合,并将集合赋值给了patents。因此就不会再次触发Linq代码了。
六.结论
Linq不会立即执行,某些操作会触发Linq执行,例如 Foreach,Count(),ToList(),ToArray() 等等。
七.注意
在使用Linq时,要避免反复执行Linq语句,这样可能会产生性能问题。