c# - 带有谓词的 .Any 是否必须在查找 .Any 之前生成结果列表

标签 c# .net performance linq-to-objects

我有一个包含 1,000,000 个复杂对象的列表。我需要使用这些对象的子集创建另一个列表,同时保持原始列表不变。在代码的这一点上,我确定 bigList 不为空,并且它至少有 1 个项目。

我的原始代码:

var smallList = bigList.Where(csvrec => csvrec.PreApprovalAmount <= 0 || csvrec.PreApprovalAmount > csvrec.ReplacementAmount).ToList();

我的团队领导说我的代码有几个问题。他说 .Where 可能导致 null,而调用 .ToList() 会导致 null 异常。因此,为了避免这种情况,他说我需要将我的代码更改为:

var smallList = new List<CSVLines>();
if(bigList.Any(csvrec => csvrec.PreApprovalAmount <= 0 || csvrec.PreApprovalAmount > csvrec.ReplacementAmount))
{
    smallList = bigList.Where(csvrec => csvrec.PreApprovalAmount <= 0 || csvrec.PreApprovalAmount > csvrec.ReplacementAmount).ToList();
}
  1. 我不认为 .Where 会导致空异常。
  2. 我不认为 smallList 永远不会为 null。这可能是一个 包含 0 个元素但不为空的列表。
  3. 用谓词做 .Any 意味着它必须生成列表,然后 确定它是否至少有 1 个元素,然后我的代码将有 再次生成相同的列表以将其分配给 smallList。

我说的对吗?我的团队领导提议的更改是否基本上使创建此列表的工作量翻了一番,却没有任何实际好处?

最佳答案

Does .Any with a predicate have to generate the resulting list before it looks for .Any

不, Enumerable.Any 不需要那样做。 MSDN:

The enumeration of source is stopped as soon as the result can be determined.

该方法接受一个序列和一个谓词,然后枚举序列直到谓词匹配一次并返回true。 .如果没有项目匹配 false被退回。因此,如果第一项已经匹配,则不需要枚举结果。在 Source -代码:

foreach (TSource element in source) {
    if (predicate(element)) return true;
}
return false;

Are the proposed changes from my team lead basically doubling the amount of work to create this list with no real benefit?

是的,首先检查是否有任何项目匹配,然后使用 Where在这种情况下,过滤是不必要的开销。它不会使开销加倍,因为 Any在第一次匹配时停止,但它是开销(如果没有匹配项,它会加倍,因为序列必须被枚举两次)。


.Where could result in null, and that calling .ToList() would cause a null exception.

不,那是不可能的。 Enumerable.Where永不返回 null ,它是输入序列的过滤器,如果没有项与谓词 Enumerable.Empty<T> 匹配被退回。

也许他很困惑,因为查询是在 ToList 处执行的, 所以如果有 NullReferenceException在查询的某处,然后您会在 ToList 处看到此异常(或执行它的任何其他方法)。查看以下抛出异常的查询:

var query = "foo".Select(c => { throw new NullReferenceException(); return 1; });
List<int> list = query.ToList(); // exception here not in first line

关于c# - 带有谓词的 .Any 是否必须在查找 .Any 之前生成结果列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47333979/

相关文章:

c# - 将 Windows Azure 移动服务添加到 Visual Studio 中的移动应用程序

c# - 从 IntPtr 句柄获取控件/表单对象

c# - 编辑 WinForms RichTextBoxControl C#

c# - Type.GetProperties 排除带有运算符 [] 的属性

.net - 如何在 VB.NET 中每 2 个数字向数字字符串添加空格?

Java 文件光标

c - 如何将父进程和子进程保持在同一个核心上

c# - 文件上传作为原子操作

c# - WinForms 属性网格不允许我更改结构值

javascript - 将脚本缓存到本地存储的basket.js概念仍然是一个好主意吗?