如何检查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个回答

2
我使用 Bool IsCollectionNullOrEmpty = !(Collection?.Any()??false);。希望这可以帮到您。
分解: Collection?.Any() 如果 Collection 为空将返回 null,如果 Collection 为空集将返回 falseCollection?.Any()??false 如果 Collection 为空集将返回 false,如果 Collection 为 null 将返回 false
它的补集将给出 IsEmptyOrNull

2
这里是Marc Gravell的回答中的代码,以及使用示例。
using System;
using System.Collections.Generic;
using System.Linq;

public static class Utils
{
    public static bool IsAny<T>(this IEnumerable<T> data)
    {
        return data != null && data.Any();
    }
}

class Program
{
    static void Main(string[] args)
    {
        IEnumerable<string> items;
        //items = null;
        //items = new String[0];
        items = new String[] { "foo", "bar", "baz" };

        /*** Example Starts Here ***/
        if (items.IsAny())
        {
            foreach (var item in items)
            {
                Console.WriteLine(item);
            }
        }
        else
        {
            Console.WriteLine("No items.");
        }
    }
}

正如他所说,不是所有的序列都是可重复的,因此该代码有时可能会出现问题,因为IsAny()会开始遍历序列。我猜Robert Harvey's answer的意思是,通常你不需要检查null空的情况。通常,你只需检查是否为空,然后使用foreach即可。
为了避免两次启动序列并利用foreach,我写了一些像这样的代码:
using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        IEnumerable<string> items;
        //items = null;
        //items = new String[0];
        items = new String[] { "foo", "bar", "baz" };

        /*** Example Starts Here ***/
        bool isEmpty = true;
        if (items != null)
        {
            foreach (var item in items)
            {
                isEmpty = false;
                Console.WriteLine(item);
            }
        }
        if (isEmpty)
        {
            Console.WriteLine("No items.");
        }
    }
}

我猜测扩展方法可以节省您输入的几行代码,但是我认为这段代码更清晰。我怀疑一些开发人员不会立即意识到 IsAny(items) 实际上会开始遍历序列。(当然,如果您使用大量序列,您很快就会学会考虑它们的步骤。)

如果在 null 上调用 IsAny,它会抛出异常。 - Aleksandar Trajkov
3
你试过了吗,@Ace?看起来好像会抛出异常,但是扩展方法可以在空实例上调用 - Don Kirkby

1
我遇到了同样的问题,解决方法如下:
    public bool HasMember(IEnumerable<TEntity> Dataset)
    {
        return Dataset != null && Dataset.Any(c=>c!=null);
    }

"

“c=>c!=null”将忽略所有的空实体。

"

1
我是基于@Matt Greer的答案构建的。
他完美地回答了问题。
我想要像这样的东西,同时保持Any的原始功能,还要检查null。我发布这个帖子,以防其他人需要类似的东西。
具体而言,我仍然希望能够传递谓词。
public static class Utilities
{
    /// <summary>
    /// Determines whether a sequence has a value and contains any elements.
    /// </summary>
    /// <typeparam name="TSource">The type of the elements of source.</typeparam>
    /// <param name="source">The <see cref="System.Collections.Generic.IEnumerable"/> to check for emptiness.</param>
    /// <returns>true if the source sequence is not null and contains any elements; otherwise, false.</returns>
    public static bool AnyNotNull<TSource>(this IEnumerable<TSource> source)
    {
        return source?.Any() == true;
    }

    /// <summary>
    /// Determines whether a sequence has a value and any element of a sequence satisfies a condition.
    /// </summary>
    /// <typeparam name="TSource">The type of the elements of source.</typeparam>
    /// <param name="source">An <see cref="System.Collections.Generic.IEnumerable"/> whose elements to apply the predicate to.</param>
    /// <param name="predicate">A function to test each element for a condition.</param>
    /// <returns>true if the source sequence is not null and any elements in the source sequence pass the test in the specified predicate; otherwise, false.</returns>
    public static bool AnyNotNull<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
    {
        return source?.Any(predicate) == true;
    }
}

扩展方法的命名可能需要改进。

0

另一个检查是否为空的最佳解决方案如下:

for(var item in listEnumerable)
{
 var count=item.Length;
  if(count>0)
  {
         // not empty or null
   }
  else
  {
       // empty
  }
}

2
如果 listEnumerable 为 null,这个方法将无法运行。这也是我们所要讨论的问题。 - Timotei

0

我使用简单的if语句来检查它

看看我的解决方案

foreach (Pet pet in v.Pets)
{
    if (pet == null)
    {
        Console.WriteLine(" No pet");// enumerator is empty
        break;
    }
    Console.WriteLine("  {0}", pet.Name);
}

0

如果为 null,则返回 true

enter    public static bool IsNullOrEmpty<T>(this IEnumerable<T> enumerable)
    {

        try
        {
            return enumerable?.Any() != true;
        }
        catch (Exception)
        {

            return true;
        }
   
    }

代码在这里


使用异常并不高效。 - Norcino

0

我使用

    list.Where (r=>r.value == value).DefaultIfEmpty().First()

如果没有匹配,结果将为null,否则返回其中一个对象。

如果您想要列表,我相信留下First()或调用ToList()将提供列表或null。


0
只需添加 using System.Linq,当您尝试访问 IEnumerable 中可用的方法时,就会看到神奇的事情发生。添加此内容将使您可以轻松访问名为 Count() 的方法。只需在调用 count() 之前记得检查 null value :)

0
我使用这个:
    public static bool IsNotEmpty(this ICollection elements)
    {
        return elements != null && elements.Count > 0;
    }

例子:

List<string> Things = null;
if (Things.IsNotEmpty())
{
    //replaces ->  if (Things != null && Things.Count > 0) 
}

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