LINQ to objects遇到的小坑
1、C#中LINQ to Objects中延迟查询的陷阱(其他类型的LINQ也基本一致)
之前在不了解LINQ延迟查询的时候,我使用下面的这种方式,将where语句的结果直接as为List<T>对象,结果得到的temp为NULL,苦思不得其解;
List<person> lst = new List<person>(){ new person(){id=1,name="cyong"}, new person(){id=2,name="lshan"} }; List<person> temp = lst.Where(m => m.id > 1) as List<person>;
求解思路:
一开始以为是LINQ语句的问题,但是在反复测试之后,发现 lst.Where(m => m.id > 1) 确实是语法正确的,并且能够在调用ToList()扩展方法后返回正确的结果集;
而后,考虑是as的问题,查看as的使用方式,发现as是类型安全的转换方式,当转换失败时不会报错,而是返回null;但是查看文档发现Where语句返回的是IEnumerable<TSource>,而IEnumerable<T>在一般情况下(比如我先将一个List<T>转换为IEnumerable<T>,再通过一次as转换回来)是可以正常转换为List<T>的;
求助:
然后就将这个问题抛给了群里面的一群大神。经过一番指点,才发现这个问题的缘由是LINQ的懒加载(延迟查询)。
上文档:
文档中介绍到【查询变量本身只存储查询命令。查询的实际执行将推迟到“foreach”语句中循环访问查询变量之后进行;同时,也可以通过ToList或者ToArray方法强制立即执行,以将查询结果缓存到单个集合对象中】
Enumerable.Where<TSource>方法(IEnumerable<TSource>,Func<TSource,Int32,Boolean>)
此方法使用的是LINQ的延迟查询。
结论:
1、LINQ查询只是缓存查询命令,要访问查询结果,应该使用foreach去迭代或者使用ToList()或者ToArray方法强制立即执行并缓存到集合对象中。
2、MSDN文档不得不看看。
附图:
1、同行指教