多次枚举和使用Any()

时间:2018-02-22 16:31:37

标签: c# .net algorithm linq

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

  • 如果有项目,请逐行打印
  • 如果没有商品,请打印"No items"

我认为这样做的方式就像

if (items.Any())
{
    foreach (string item in items)
    {
        Console.WriteLine(item);
    }
}
else
{
    Console.WriteLine("No items");
}

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

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

但显然,那不那么优雅。

3 个答案:

答案 0 :(得分:4)

既然我们正在谈论LINQ,那么LINQ解决方案呢?

foreach (var item in items.DefaultIfEmpty("No items"))
    Console.WriteLine(item);

答案 1 :(得分:0)

var itemsList = items as List<Item> ?? items.ToList();

如果IEnumerable<Item>已经是一个列表,那么您已经设置好了。如果没有,则调用.ToList()。无论哪种方式,你最终得到一个列表。 (Resharper默认为一个数组。我正在显示一个符合某些注释的列表。)

答案 2 :(得分:-1)

根据您的使用情况,这可能是也可能不是问题,因为Any()会在满足条件时立即短路,这意味着不需要枚举整个IEnumerable。

请注意下面的评论,这些评论指出了潜在的陷阱,例如实施只是前进或昂贵。

这是reference source

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;
}