建议检查序列是否为空的方法

时间:2010-01-19 15:47:09

标签: c# linq ienumerable

方法返回一个序列IEnumerable<T>,您现在想要检查它是否为空。你怎么建议这样做?我正在寻找良好的可读性和良好的性能。

第一种也是最明显的方法是检查计数是否大于零:

if(sequence.Count() == 0)

具有良好的可读性,但性能很差,因为它必须实际完成整个序列。

我有时使用的方法如下:

if(!sequence.Any())

这不(据我所知)必须经历整个序列,但可读性有点倒退和尴尬。 (如果我们检查序列为空,则读得更好。)

另一个选择是在try-catch中使用First,如下所示:

try
{
    sequence.First();
}
catch(InvalidOperationException)
{
    // Do something
}

不是一个非常漂亮的解决方案,也可能更慢,因为它使用异常和东西。当然可以使用FirstOrDefault来阻止这种情况,但如果序列中的第一项 是的默认值,则会出现大问题;)

那么,检查序列是否为空的任何其他方法?你经常使用哪一个?你建议使用哪一个?

注意: 为了获得最佳的可读性,我可能会将上述代码段中的一个放在IsEmpty扩展方法中,但我仍然很好奇,因为我也必须在该方法中做一些事情:p

6 个答案:

答案 0 :(得分:81)

我会亲自使用!sequence.Any()

如果确实需要,您可以随时编写自己的扩展方法:

public static bool IsEmpty<T>(this IEnumerable<T> source)
{
    return !source.Any();
}

然后你可以写:

if (sequence.IsEmpty())

答案 1 :(得分:5)

您可以使用此实现创建Extension方法。

public static bool IsEmpty<T>(this IEnumerable<T> items) {
        using (var enumerator = items.GetEnumerator())
        {
            return !enumerator.MoveNext();
        }
 }

答案 2 :(得分:2)

您调用的所有这些方法都是LINQ扩展方法,因此它取决于LINQ提供程序的实现方式。如果您想知道序列是否为空,则Count() == 0Any() == false是合适的。我自己更喜欢Any()

但是,根据您的sequence的实际类型,您可能不需要使用LINQ扩展方法。即如果它是一个数组,你可以调用sequence.Length。如果它是一个集合,您可以使用sequence.Count

答案 3 :(得分:0)

你说:

  

if(sequence.Count() == 0)   具有良好的可读性,但性能可怕,因为它必须实际完成整个序列。

这是真的吗?您正在讨论处理接口IEnumerable<T>,但您正在对其实现进行假设,这可能是也可能不是。事实上,我多年来编写的许多自定义集合都保留了一个私有变量,用于在内部存储当前计数,这意味着返回.Count是一件微不足道的事情,不需要迭代整个集合。

因此,除非您知道某个特定实现针对.Count进行了优化,否则我会使用.Count。尽可能避免过早优化,并坚持可读性。

答案 4 :(得分:0)

  

我有时使用的方法如下:

b.h
     

这不(据我所知)必须经历整个序列,   但可读性有点倒退和尴尬。 (读了很多   如果我们检查序列不是空的,那就更好了。

  1. 根据微软的说法,Any确实必须经历整个序列。引自备注
  2. 部分
      

    结果可以立即停止if(!sequence.Any()) 的枚举   确定。

    1. 在测试source语句中是否存在元素时尤其如此。可以说,如果检测if-else语句中元素的存在以及if中缺少元素,那么可读性最好,从而避免使用else运算符:

      !

      大多数人会认为比以下更具可读性

      if (sequence.Any())
      {
      }
      else
      {
      }
      

答案 5 :(得分:-1)

我使用此扩展方法来检测序列是否为空或者没有任何项目,或者检测序列是否至少有一个项目,就像string.IsNullOrEmpty()方法一样。

 public static bool IsNullOrEmpty<TSource>(this IEnumerable<TSource> source) {
     if (source == null) {
        return true;
     }

     return !source.Any();
 }

 public static bool IsNotNullOrEmpty<TSource>(this IEnumerable<TSource> source) {
     return !source.IsNullOrEmpty();
 }
 .
 .
 .
 if (!sequence.IsNullOrEmpty()) {
     //Do Something with the sequence...
 }