我应该在LINQ查询中使用两个“ where”子句还是“ &&”?


76

当编写具有多个“和”条件的LINQ查询时,我是否应该编写一个where包含&&或多个where子句的子句,每个条件一个?

static void Main(string[] args)
{
    var ints = new List<int>(Enumerable.Range(-10, 20));

    var positiveEvensA = from i in ints
                         where (i > 0) && ((i % 2) == 0)
                         select i;

    var positiveEvensB = from i in ints
                         where i > 0
                         where (i % 2) == 0
                         select i;

    System.Diagnostics.Debug.Assert(positiveEvensA.Count() == 
                                         positiveEvensB.Count());
}

positiveEvensApositiveEvensB之间除了个人喜好或编码风格(长行,可读性等)之外,是否有其他区别?

我想到的一个可能的区别是,不同的LINQ提供程序可能能够更好地处理多个wheres,而不是更复杂的表达式。这是真的?

Answers:


53

我个人将始终使用&& vs. where子句,只要它不会使语句难以理解。

在您的情况下,它可能根本不会引起注意,但是如果您有大量集合并且使用了此查询的所有结果,那么拥有2个where子句肯定会对性能产生影响。例如,如果在结果上调用.Count()或遍历整个列表,则第一个where子句将运行,创建一个新的IEnumerable <T>,将使用第二个委托再次对其进行完全枚举。

将2个子句链接在一起会使查询形成单个委托,该委托在枚举集合时将运行。这将导致对集合进行一次枚举,并在每次返回结果时对委托进行一次调用。

如果拆分它们,情况将会改变。当您的第一个where子句枚举原始集合时,第二个where子句枚举其结果。这可能(在最坏的情况下)导致通过集合进行2次完整枚举,并为每个成员调用2个委托,这可能意味着该语句(理论上)可能需要2倍的运行速度。

如果您确实决定使用2个where子句,则将限制性更强的子句放在第一位会很有帮助,因为第二个where子句仅在传递第一个条件的元素上运行。

现在,就您而言,这无关紧要。在一个大集合中,它可以。作为一般经验法则,我建议:

  1. 可读性和可维护性

  2. 性能

在这种情况下,我认为这两个选项都可维护,因此我会选择性能更高的选项。


38
有了2个“ where”子句,那仍然只是一个单次迭代,每个项有2个委托调用-而不是要求的2次迭代。
马克·格雷韦尔

5
马克,当我说两次迭代时,我应该更加明确。使用2个where子句,您必须构造两个单独的枚举数-第一个where创建一个枚举数,第二个枚举数。但这是很小的事情-它没有执行2个循环,仅使用单独的枚举器进行枚举。
里德·科普西

3
我认为Where对于多where子句情况有一些特殊的优化。仍然由于多个委托调用而变慢。
CodesInChaos 2011年

21

这主要是个人风格问题。就个人而言,只要该where子句适合一行,我就将这些子句分组。

使用multi wheres往往会降低性能,因为它需要为使它走那么远的每个元素额外委托调用。但是,这可能是无关紧要的问题,只有在探查器显示它是问题时才应考虑。



1

就像其他人建议的那样,这更多是个人喜好。我喜欢使用&&,因为它更具可读性,并且模仿其他主流语言的语法。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.