How to check if IEnumerable is null or empty?

2020-01-24 19:40发布

I love string.IsNullOrEmpty method. I'd love to have something that would allow the same functionality for IEnumerable. Is there such? Maybe some collection helper class? The reason I am asking is that in if statements the code looks cluttered if the patter is (mylist != null && mylist.Any()). It would be much cleaner to have Foo.IsAny(myList).

This post doesn't give that answer: IEnumerable is empty?.

19条回答
趁早两清
2楼-- · 2020-01-24 20:13

I used simple if to check for it

check out my solution

foreach (Pet pet in v.Pets)
{
    if (pet == null)
    {
        Console.WriteLine(" No pet");// enumerator is empty
        break;
    }
    Console.WriteLine("  {0}", pet.Name);
}
查看更多
看我几分像从前
3楼-- · 2020-01-24 20:15

The other best solution as below to check empty or not ?

for(var item in listEnumerable)
{
 var count=item.Length;
  if(count>0)
  {
         // not empty or null
   }
  else
  {
       // empty
  }
}
查看更多
家丑人穷心不美
4楼-- · 2020-01-24 20:15

just add using System.Linq and see the magic happening when you try to access the available methods in the IEnumerable. Adding this will give you access to method named Count() as simple as that. just remember to check for null value before calling count() :)

查看更多
冷血范
5楼-- · 2020-01-24 20:16

Here's the code from Marc Gravell's answer, along with an example of using it.

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.");
        }
    }
}

As he says, not all sequences are repeatable, so that code may sometimes cause problems, because IsAny() starts stepping through the sequence. I suspect what Robert Harvey's answer meant was that you often don't need to check for null and empty. Often, you can just check for null and then use foreach.

To avoid starting the sequence twice and take advantage of foreach, I just wrote some code like this:

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.");
        }
    }
}

I guess the extension method saves you a couple of lines of typing, but this code seems clearer to me. I suspect that some developers wouldn't immediately realize that IsAny(items) will actually start stepping through the sequence. (Of course if you're using a lot of sequences, you quickly learn to think about what steps through them.)

查看更多
手持菜刀,她持情操
6楼-- · 2020-01-24 20:17

I built this off of the answer by @Matt Greer

He answered the OP's question perfectly.

I wanted something like this while maintaining the original capabilities of Any while also checking for null. I'm posting this in case anyone else needs something similar.

Specifically I wanted to still be able to pass in a predicate.

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

The naming of the extension method could probably be better.

查看更多
闹够了就滚
7楼-- · 2020-01-24 20:23

Another way would be to get the Enumerator and call the MoveNext() method to see if there are any items:

if (mylist != null && mylist.GetEnumerator().MoveNext())
{
    // The list is not null or empty
}

This works for IEnumerable as well as IEnumerable<T>.

查看更多
登录 后发表回答