如何检查IEnumerable是否为空或为空?

211
我喜欢 string.IsNullOrEmpty 方法。我希望有一个类似的方法可以用于 IEnumerable。是否有这样的方法?也许有一些集合辅助类?我之所以问这个问题是因为在 if 语句中,如果模式是 (mylist != null && mylist.Any()),代码看起来很凌乱。如果有 Foo.IsAny(myList),将会更加清晰。
这篇文章没有给出答案:IEnumerable is empty?

1
如果这不是评论,我可能会给你答案 :) - Schultz9999
2
在我看来,这似乎是一个 XY 问题。你应该问“如何改进我的设计,以便我不必到处检查 null?”而不是问“如何在所有地方精确检查 null 而不那么麻烦?” - sara
1
你可以使用以下代码替代:myCollection?.FirstOrDefault() == null - Adel Tabareh
23个回答

0

由于某些资源在一次读取后就会被耗尽,所以我想为什么不将检查和读取结合起来,而不是传统的分开检查,然后读取。

首先,我们有一个更简单的内联扩展程序用于检查空值:

public static System.Collections.Generic.IEnumerable<T> ThrowOnNull<T>(this System.Collections.Generic.IEnumerable<T> source, string paramName = null) => source ?? throw new System.ArgumentNullException(paramName ?? nameof(source));

var first = source.ThrowOnNull().First();

然后我们有一个稍微复杂一些的(至少我写的方式是这样)检查 null 和空字符串的内联扩展:

public static System.Collections.Generic.IEnumerable<T> ThrowOnNullOrEmpty<T>(this System.Collections.Generic.IEnumerable<T> source, string paramName = null)
{
  using (var e = source.ThrowOnNull(paramName).GetEnumerator())
  {
    if (!e.MoveNext())
    {
      throw new System.ArgumentException(@"The sequence is empty.", paramName ?? nameof(source));
    }

    do
    {
      yield return e.Current;
    }
    while (e.MoveNext());
  }
}

var first = source.ThrowOnNullOrEmpty().First();

你当然可以在不继续调用的情况下同时调用两个函数。此外,我还包含了paramName,以便调用者在检查错误时可以使用替代名称,例如"nameof(target)"而不是"source"。

0
 public static bool AnyNotNull<TSource>(this IEnumerable<TSource> source)
    {
        return source != null && source.Any();
    }

我的自定义扩展方法用于检查非空和任何


0
没有自定义的助手,我建议使用?.Any() ?? false?.Any() == true,它们相对简洁,只需要指定一次序列即可。

当我想把一个缺失的集合当作一个空的集合来处理时,我使用以下扩展方法:

public static IEnumerable<T> OrEmpty<T>(this IEnumerable<T> sequence)
{
    return sequence ?? Enumerable.Empty<T>();
}

这个函数可以与所有的LINQ方法和foreach结合使用,而不仅仅是.Any(),这就是为什么我更喜欢它而不是人们在这里提出的更专业的辅助函数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接