Eric Yin
Eric Yin

Reputation: 8973

Does C# have IsNullOrEmpty for List/IEnumerable?

I know generally empty List is more prefer than NULL. But I am going to return NULL, for mainly two reasons

  1. I have to check and handle null values explicitly, avoiding bugs and attacks.
  2. It is easy to perform ?? operation afterwards to get a return value.

For strings, we have IsNullOrEmpty. Is there anything from C# itself doing the same thing for List or IEnumerable?

Upvotes: 82

Views: 106710

Answers (13)

EvilDr
EvilDr

Reputation: 9632

I noticed today that .Net Core 7.6.2 has the extension CollectionUtilities.IsNullOrEmpty<T>(IEnumerable<T>) Method in Microsoft.Identitymodel.Tokens.CollectionUtilities.

This seems a very odd place to keep it IMHO, but if you're using that package then it is available...

Upvotes: 1

M.Hassan
M.Hassan

Reputation: 11032

One-line with nullable support:

public static bool IsNullOrEmpty<T>(this IEnumerable<T>? enumerable) => 
            enumerable == null || !enumerable.Any();

Upvotes: 0

Grigor Yeghiazaryan
Grigor Yeghiazaryan

Reputation: 197

 public static class IEnumerableExtention
 {
     public static bool IsNullOrEmpty<T>(this IEnumerable<T> enumerable)
     {
         if (enumerable == null)
         {
             return true;
         }
 
         using var enumerator = enumerable.GetEnumerator();
 
         var isEmpty = !enumerator.MoveNext();
 
         return isEmpty;
     }
 }

Upvotes: 0

Teodor Tite
Teodor Tite

Reputation: 1955

Late update: since C# 6.0, the null-propagation operator may be used to express concise like this:

if (  list?.Count  > 0 ) // For List<T>
if ( array?.Length > 0 ) // For Array<T>

or, as a cleaner and more generic alternative for IEnumerable<T>:

if ( enumerable?.Any() ?? false )

Note 1: all upper variants reflect actually IsNotNullOrEmpty, in contrast to OP question (quote):

Because of operator precedence IsNullOrEmpty equivalents look less appealing:
if (!(list?.Count > 0))

Note 2: ?? false is necessary, because of the following reason (summary/quote from this post):

?. operator will return null if a child member is null. But [...] if we try to get a non-Nullable member, like the Any() method, that returns bool [...] the compiler will "wrap" a return value in Nullable<>. For example, Object?.Any() will give us bool? (which is Nullable<bool>), not bool. [...] Since it can't be implicitly casted to bool this expression cannot be used in the if

Note 3: as a bonus, the statement is also "thread-safe" (quote from answer of this question):

In a multithreaded context, if [enumerable] is accessible from another thread (either because it's a field that's accessible or because it's closed over in a lambda that is exposed to another thread) then the value could be different each time it's computed [i.e.prior null-check]

Upvotes: 65

Matthew Vines
Matthew Vines

Reputation: 27561

nothing baked into the framework, but it's a pretty straight forward extension method.

See here

/// <summary>
    /// Determines whether the collection is null or contains no elements.
    /// </summary>
    /// <typeparam name="T">The IEnumerable type.</typeparam>
    /// <param name="enumerable">The enumerable, which may be null or empty.</param>
    /// <returns>
    ///     <c>true</c> if the IEnumerable is null or empty; otherwise, <c>false</c>.
    /// </returns>
    public static bool IsNullOrEmpty<T>(this IEnumerable<T> enumerable)
    {
        if (enumerable == null)
        {
            return true;
        }
        /* If this is a list, use the Count property for efficiency. 
         * The Count property is O(1) while IEnumerable.Count() is O(N). */
        var collection = enumerable as ICollection<T>;
        if (collection != null)
        {
            return collection.Count < 1;
        }
        return !enumerable.Any(); 
    }

Daniel Vaughan takes the extra step of casting to ICollection (where possible) for performance reasons. Something I would not have thought to do.

Upvotes: 85

keipa
keipa

Reputation: 792

for me best isNullOrEmpty method is looked like this

public static bool IsNullOrEmpty<T>(this IEnumerable<T> enumerable)
{
    return !enumerable?.Any() ?? true;
}

Upvotes: 0

Xipooo
Xipooo

Reputation: 1566

Putting together the previous answers into a simple extension method for C# 6.0+:

    public static bool IsNullOrEmpty<T>(this IEnumerable<T> me) => !me?.Any() ?? true;

Upvotes: 4

eddy white
eddy white

Reputation: 303

var nullOrEmpty = !( list?.Count > 0 );

Upvotes: 0

Georg
Georg

Reputation: 2096

I modified the suggestion from Matthew Vines to avoid the "Possible multiple enumeration of IEnumerable" - problem. (see also the comment from Jon Hanna)

public static bool IsNullOrEmpty(this IEnumerable items)
    => items == null
    || (items as ICollection)?.Count == 0
    || !items.GetEnumerator().MoveNext();

... and the unit test:

[Test]
public void TestEnumerableEx()
{
    List<int> list = null;
    Assert.IsTrue(list.IsNullOrEmpty());

    list = new List<int>();
    Assert.IsTrue(list.IsNullOrEmpty());

    list.AddRange(new []{1, 2, 3});
    Assert.IsFalse(list.IsNullOrEmpty());

    var enumerator = list.GetEnumerator();
    for(var i = 1; i <= list.Count; i++)
    {
        Assert.IsFalse(list.IsNullOrEmpty());
        Assert.IsTrue(enumerator.MoveNext());
        Assert.AreEqual(i, enumerator.Current);
    }

    Assert.IsFalse(list.IsNullOrEmpty());
    Assert.IsFalse(enumerator.MoveNext());
}

Upvotes: 0

Matt Frear
Matt Frear

Reputation: 54811

As everyone else has said, nothing is built into the framework, but if you are using Castle then Castle.Core.Internal has it.

using Castle.Core.Internal;

namespace PhoneNumbers
{
    public class PhoneNumberService : IPhoneNumberService
    {
        public void ConsolidateNumbers(Account accountRequest)
        {
            if (accountRequest.Addresses.IsNullOrEmpty()) // Addresses is List<T>
            {
                return;
            }
            ...

Upvotes: 2

Oded
Oded

Reputation: 498992

There is nothing built in.

It is a simple extension method though:

public static bool IsNullOrEmpty<T>(this IEnumerable<T> enumerable)
{
  if(enumerable == null)
    return true;

  return !enumerable.Any();
}

Upvotes: 27

Jon Hanna
Jon Hanna

Reputation: 113242

If you need to be able to retrieve all of the elements in the case of it not being empty, then some of the answers here won't work, because the call to Any() on a non-rewindable enumerable will "forget" an element.

You could take a different approach and turn nulls into empties:

bool didSomething = false;
foreach(var element in someEnumeration ?? Enumerable.Empty<MyType>())
{
  //some sensible thing to do on element...
  didSomething = true;
}
if(!didSomething)
{
  //handle the fact that it was null or empty (without caring which).
}

Likewise (someEnumeration ?? Enumerable.Empty<MyType>()).ToList() etc. can be used.

Upvotes: 2

Justin Niessner
Justin Niessner

Reputation: 245419

var nullOrEmpty = list == null || !list.Any();

Upvotes: 11

Related Questions