在编写具有多个"and"条件的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提供者可能能够更好地处理多个where,而不是更复杂的表达式;这是真的吗?

推荐答案

我个人会一直支持&&;vs.两个where从句,只要它不会让陈述变得难以理解.

在你的例子中,它可能根本不会被注意到,但是如果你有一个大的集合,如果你使用这个查询的所有结果,那么有两个where子句肯定会对性能产生影响.例如,如果你打电话.Count(),或者遍历整个列表,第一个where子句将运行,创建一个新的IEnumerable<;T>;这将通过第二个委托再次完全枚举.

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

如果你把它们分开,事情就会改变.当第一个where子句在原始集合中枚举时,第二个where子句将枚举其结果.这可能会导致(最坏的情况)在集合中进行2次完整枚举,每个成员调用2次委托,这可能意味着(理论上)此语句可能需要2倍的运行速度.

如果您确实决定使用2个where子句,那么将限制性更强的子句放在第一位会有很大帮助,因为第二个where子句只在通过第一个where子句的元素上运行.

现在,在你的情况下,这无关紧要.在一大批藏品上,这是可能的.作为一般的经验法则,我认为:

  1. 可读性和可维护性

  2. 性能

在这种情况下,我认为这两个选项都是可维护的,所以我会 Select 性能更好的选项.

.net相关问答推荐

DI通过对象的接口而不是实际类型来解析服务

cmd 冻结中的 dotnet 命令.怎么了?

既然 .NET 有一个垃圾收集器,为什么我们需要终结器/析构器/dispose-pattern?

为什么这两个比较有不同的结果?

.gitignore 和 Visual Studio 项目:忽略 bin/Debug 目录但不忽略 bin/Release 目录

比较 C# 中的双精度值

防止对话框在按钮的单击事件处理程序中关闭

是否有用于 Windows / C# 开发的可嵌入 Webkit 组件?

操作对事务的状态无效错误和事务范围

覆盖方法上的 C# 可选参数

将接收到的对象转换为 List 或 IEnumerable

Convert.ToBoolean 和 Boolean.Parse 不接受 0 和 1

如何异步 Files.ReadAllLines 并等待结果?

等待 Async Void 方法调用以进行单元测试

如何仅在需要时提升权限?

在任务中捕获异常的最佳方法是什么?

了解 C# 中的协变和逆变接口

在 C#/.NET 中合并两个图像

没有科学记数法的双精度字符串转换

多行 C# 插值字符串文字