一个朋友给我看了这条Linq语句:
records.Where( r => r.Name == "Henry Clay" ).FirstOrDefault();抛开FirstOrDefault()可以接受lambda的事实不谈,是在所有Henry Clay记录都转到FirstOrDefault()之前检查它们是否有"Henry Clay“,还是Where方法只返回第一个记录?
换句话说,有些Henry Clay记录永远不会传递给FirstOrDefault吗?
发布于 2012-10-30 04:30:09
不,所有的元素都是延迟执行的。当您按如下方式重写查询时,您可以看到这一点:
records.Where(r =>
{
Console.WriteLine(r.Name);
return r.Name == "Henry Clay";
})
.FirstOrDefault();当你强制执行时,结果会有很大不同,例如ToArray():
records.Where(r =>
{
Console.WriteLine(r.Name);
return r.Name == "Henry Clay";
})
.ToArray()
.FirstOrDefault();在最后一种情况下,ToArray()将强制迭代records集合中的所有元素,否则,FirstOrDefault()将确保在where谓词首次返回true之后停止迭代集合。
发布于 2012-10-30 04:29:25
假设您在末尾之前找到了一项,那么您将不会迭代整个源序列。一旦第一项返回,您将立即停止。
这里有一个有用的类比。想象一下,一群人坐在一张桌子旁。“迈克”坐在最左边。每当他旁边的人向他索要物品时,他就会从一堆纸中拿出一张纸,递给下一个人。他将成为底层数据records的“枚举器”。
坐在他旁边的将是“弗雷德”。当有人问佛瑞德要东西时,他会向迈克要东西。如果Mike给他的东西上写着"Henry Clay“,那么他就会把它给下一个人,如果没有,他会问Mike要另一件东西。这将一直持续下去,直到Fred最终获得满足他的条件的物品,或者Mike用完物品。他代表的是Where枚举器。
弗雷德的右边是"Aaron“。当Aaron被要求提供物品时,他会向Fred索要物品。当他从Fred那里得到一件物品时,他会把它传递给下一个人,然后当下一次有人要求物品时,他会立即说“不,我已经做完了”,而不会要求Fred做其他任何事情。他是FirstOrDefault的律师。
每个人,当被要求从他们旁边的人那里获得一个项目时,只有当被要求时,才会从他们的“源”中获得一个项目,处理它,或者做他们需要做的任何事情,以便为下一个人生成一个项目。你可以想象,使用这个例子,一旦Aaron拿到了他的第一件东西,堆栈上很可能会剩下一张纸。他们将留在那里,任何人都不会处理,因为Aaron永远不会向Fred索要他的第二件物品。
https://stackoverflow.com/questions/13129081
复制相似问题