Any() 的多重枚举和使用

use*_*000 7 .net c# linq algorithm

当我需要执行以下操作时,我试图找出 LINQ 的正确约定是什么

  • 如果有项目,则逐行打印它们
  • 如果没有项目,则打印"No items"

我想这样做的方式就像

if (items.Any())
{
    foreach (string item in items)
    {
        Console.WriteLine(item);
    }
}
else
{
    Console.WriteLine("No items");
}
Run Code Online (Sandbox Code Playgroud)

然而,这在技术上违反了多重枚举原则。一种不违反这一点的方法是

bool any = false;
foreach (string item in items)
{
    any = true;
    Console.WriteLine(item);
}   
if (!any)
{
    Console.WriteLine("No items");
}
Run Code Online (Sandbox Code Playgroud)

但显然,这不太优雅。

Owe*_*ing -1

这可能是也可能不是问题,具体取决于您的用例,因为一旦满足条件,Any() 就会短路,这意味着不需要枚举整个 IEnumerable。

请注意下面的评论,其中指出了潜在的陷阱,例如仅向前实施或昂贵的实施。

这是参考来源

public static bool Any<TSource>(this IEnumerable<TSource> source) {
    if (source == null) throw Error.ArgumentNull("source");
    using (IEnumerator<TSource> e = source.GetEnumerator()) {
        if (e.MoveNext()) return true;
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)

  • 太多的“假设”与实际问题无关。没有明确的性能问题。没有规定的自定义列表类型。垃圾评论太多了。 (3认同)
  • 如果实施只是转发并且执行操作或者成本昂贵怎么办?执行 .Any() 可能会出现问题 (2认同)
  • 这确实是一个问题。不仅因为即使是“.Any()”也可能很昂贵,而且因为枚举两次可能会产生不同的结果。 (2认同)