我一直在阅读有关使用LINQ的性能,而不是使用每个循环的性能,并且从我理解的使用LINQ查询会稍微慢一点但是为了方便和表现力通常是值得的。但是,如果你在for循环中使用查询结果,我会感到有点困惑。
假设我有一个名为'Locations'的集合和一组名为'Items'的对象。每个“项目”只能属于一个“位置”。我想将相同位置下的项链接到彼此。如果我使用正常的'For Each'循环来执行此操作,它将是这样的:
For Each it as Item in Items
If it.Location.equals(Me.Location)
Me.LinkedItems.Add(it)
End If
Next
但是如果我要使用LINQ,那就是:
For Each it as Item in Items.Where(Function(i) i.Location.equals(Me.Location))
Me.LinkedItems.Add(it)
Next
现在我的问题是,第二个(LINQ)选项是否会循环遍历整个'Items'集以完成查询,然后遍历结果以将它们添加到列表中,从而导致基本上两个循环,或者它会像第一个(For Each)选项那样进行一个循环吗?如果答案是前者,那么我认为在这种情况下使用LINQ会很愚蠢。
答案 0 :(得分:8)
它会做一个循环 - 它被懒惰地评估。
但是,你可能比这更好。 LinkedItems
的类型是什么?如果它具有适当的AddRange
方法,您应该能够:
Me.LinkedItems.AddRange(Items.Where(Function(i) i.Location.equals(Me.Location)))
有关延迟评估的更多信息
基本上Where
维护一个迭代器,只在你要求时找到下一个匹配项。在C#中,实现类似于:
// Error handling omitted
public static IEnumerable<T> Where(this IEnumerable<T> source,
Func<T, bool> predicate)
{
foreach (T element in source)
{
if (predicate(element))
{
yield return element;
}
}
}
这里使用yield return
这会使其懒惰评估。如果您不熟悉C#迭代器块,可能需要查看these articles,它们会更详细地解释它们。
当然Where
可以实现“手动”而不是使用迭代器块,但上面的实现足以显示延迟评估。
答案 1 :(得分:3)
它将执行一次查询,因为您正在预订Items.Where列表。在你的情况下,这是你想要的条件的预过滤列表,你应该真的使用LINQ。