207

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?.

Community
  • 1
  • 1
Schultz9999
  • 8,717
  • 8
  • 48
  • 87
  • 1
    @msarchet: I'd probably give you the answer if this weren't the comment :) – Schultz9999 Feb 18 '11 at 23:14
  • 2
    to me this seems like kind of an XY problem. instead of asking "how can I check for null exactly everywhere without it being so bothersome" you should ask "how can I improve my design so I won't HAVE to check for null everywhere?" – sara Apr 02 '16 at 13:01
  • 1
    You can use the following line instead: myCollection?.FirstOrDefault() == null – Adel Tabareh May 20 '21 at 06:21

23 Answers23

238

Sure you could write that:

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

however, be cautious that not all sequences are repeatable; generally I prefer to only walk them once, just in case.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • 13
    Is this a good pattern? I would drop the `this` there – I consider extension methods which are assumed to be called on `null` as a sign of ugly design. – Mormegil Feb 18 '11 at 22:49
  • 38
    @Mormegil Why? extension methods finally give C# some capability to work with nulls, which other languages (like Ruby) completely take for granted. – Matt Greer Feb 18 '11 at 22:54
  • 6
    Why is this _necessarily_ bad? As in this case, it is sometimes very handy since it lets you treat things more homogeneously and with fewer special cases. – Mr. Putty Feb 18 '11 at 22:54
  • 6
    @Mormegil meh - I can't get excited about that. As long as the intent is clear, etc. – Marc Gravell Feb 18 '11 at 22:55
  • 2
    I see nothing wrong with it, as long as there's no implication that it shouldn't be null. – Gabe Feb 18 '11 at 23:00
  • @Marc: I surely could. However I was wondering why wouldn't .NET have something like it? Seems quite handy. – Schultz9999 Feb 18 '11 at 23:12
  • 1
    @Schultz9999 in *general*, `null` is different enough to warrant different treatment... – Marc Gravell Feb 18 '11 at 23:15
  • @Marc: agree. Although if the utility class is in System.Collections namespace, I'd say it would be obvious how `null` is handled. – Schultz9999 Feb 18 '11 at 23:22
  • 2
    Even C++ allows `this` to be `null`. You can call non-virtual functions on null objects, which I have actually found useful once or twice in the past. – Hank Schultz Sep 17 '13 at 15:24
  • I think this merely makes for a poor excuse to not manage nulls in your code in general. I'm hard pressed to think of ANY situation where I'd see an IEnumerable reference be null and NOT think "wow that is some sloppy code right there". this method lets you check for nulls, true. I'd prefer to never ever assign null to an IEnumerable and just never check for null (if it crashes it's a bug, fix it instead of hiding it). – sara Apr 02 '16 at 12:59
  • 3
    Can you clarify this: "not all sequences are repeatable; generally I prefer to only walk them once"? What does calling data.Any() have to do with a sequence? – Miryafa Jul 18 '17 at 16:29
  • 12
    @Miryafa `.Any()` is an extension method that operates on `IEnumerable` (or `IQueryable`, although that's a different scenario). Doing so **consumes the sequence**, at least partially (although that still means it is consumed) - it might only need to read one element (especially if there is no predicate). As such, since sequences (`IEnumerable`) do not need to be repeatable, **that might be it**. `Any()` without a predicate is *essentially* equivalent to `foreach(var x in sequence) { return true; } return false;` - although it uses `GetEnumerator()` etc instead of compiler syntax – Marc Gravell Jul 18 '17 at 16:44
  • 4
    @MarcGravell Got it - thanks! In other words, some sequences are changed when traversed, and Any() traverses the sequence. – Miryafa Jul 19 '17 at 14:43
  • @Miryafa yes, exactly – Marc Gravell Jul 19 '17 at 15:17
  • For the non-generic `IEnumerable` (i.e. where `Any()` isn't provided by `System.Linq`, is there a good alternative? e.g. `.OfType().Any()` or `.GetEnumerator().MoveNext()` (per https://social.msdn.microsoft.com/Forums/en-US/964240c5-4d2c-4734-a12c-5ae850ff17a4/best-practice-for-testing-empty-nongeneric-ienumerable?forum=silverlightnet). Thanks in advance. – JohnLBevan Nov 22 '18 at 10:42
  • 1
    @JohnLBevan how about: `public static class EnumerableExtensions { public static bool Any(this IEnumerable sequence) { if (sequence is ICollection l) return l.Count != 0; var iter = sequence.GetEnumerator(); using (iter as IDisposable) { return iter.MoveNext(); } } }` - then you can use `.Any()` just like before – Marc Gravell Nov 22 '18 at 10:44
133
public static bool IsNullOrEmpty<T>(this IEnumerable<T> enumerable) {
    return enumerable == null || !enumerable.Any();
}
Matt Greer
  • 60,826
  • 17
  • 123
  • 123
31

Here's a modified version of @Matt Greer's useful answer that includes a static wrapper class so you can just copy-paste this into a new source file, doesn't depend on Linq, and adds a generic IEnumerable<T> overload, to avoid the boxing of value types that would occur with the non-generic version. [EDIT: Note that use of IEnumerable<T> does not prevent boxing of the enumerator, duck-typing can't prevent that, but at least the elements in a value-typed collection will not each be boxed.]

using System.Collections;
using System.Collections.Generic;

public static class IsNullOrEmptyExtension
{
    public static bool IsNullOrEmpty(this IEnumerable source)
    {
        if (source != null)
        {
            foreach (object obj in source)
            {
                return false;
            }
        }
        return true;
    }

    public static bool IsNullOrEmpty<T>(this IEnumerable<T> source)
    {
        if (source != null)
        {
            foreach (T obj in source)
            {
                return false;
            }
        }
        return true;
    }
}
yoyo
  • 8,310
  • 4
  • 56
  • 50
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>.

Darren
  • 4,408
  • 4
  • 39
  • 57
  • 4
    Should you call dispose on this enumerator? If the collection is multithreading aware? Yes. http://stackoverflow.com/questions/13459447/do-i-need-to-consider-disposing-of-any-ienumerablet-i-use – TamusJRoyce Mar 10 '15 at 16:24
  • 4
    @TamusJRoyce Note that your statement is only true for `IEnumerable`, as non-generic `IEnumerable` doesn't implement `IDisposable`. – Ian Kemp Feb 18 '16 at 12:43
22
if (collection?.Any() == true){
    // if collection contains one or more items
}
if (collection?.Any() != true){
    // if collection is null
    // if collection does not contain any item
}
Scholtz
  • 2,878
  • 2
  • 23
  • 23
14

The way I do it, taking advantage of some modern C# features:

Option 1)

public static class Utils {
    public static bool IsNullOrEmpty<T>(this IEnumerable<T> list) {
        return !(list?.Any() ?? false);
    }
}

Option 2)

public static class Utils {
    public static bool IsNullOrEmpty<T>(this IEnumerable<T> list) {
        return !(list?.Any()).GetValueOrDefault();
    }
}

And by the way, never use Count == 0 or Count() == 0 just to check if a collection is empty. Always use Linq's .Any()

Ronald Rey
  • 584
  • 7
  • 8
  • 3
    Count == 0 is just fine.... Maybe faster than Any()? However you are correct on the Count() == 0 being bad. For those that are wondering Count() iterates through your entire collection, so if it's huge could add a ton of overhead! – Anthony Nichols Dec 15 '16 at 15:56
  • Count() only iterates the enumeration if it can't be cast to an ICollection. In other words, when you call this method, if there's already a Count property on the object, it will just return that and the performance should be identical. Check out the implementation here: https://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,1191 – Ronald Rey Dec 16 '16 at 13:13
  • If you are working with an IEnumerable, using Count() to test for emptyness is definitely a bad idea since the Linq implementation WILL iterate over the entire collection, while Any will just move the iterator once. Keep in mind that you can't use the Count property in this case since it's not part of the IEnumerable interface. That's why is always a better idea to just use Any() to test for emptyness in all scenarios, in my opinion. – Ronald Rey Dec 16 '16 at 13:16
  • 1
    Nice example of how not-readable negation operator `!` can be, specially in the second option ;) – Fabio Oct 05 '17 at 08:11
9

Starting with C#6 you can use null propagation: myList?.Any() == true

If you still find this too cloggy or prefer a good ol' extension method, I would recommend Matt Greer and Marc Gravell's answers, yet with a bit of extended functionality for completeness.

Their answers provide the same basic functionality, but each from another perspective. Matt's answer uses the string.IsNullOrEmpty-mentality, whereas Marc's answer takes Linq's .Any() road to get the job done.

I am personally inclined to use the .Any() road, but would like to add the condition checking functionality from the method's other overload:

    public static bool AnyNotNull<T>(this IEnumerable<T> source, Func<T, bool> predicate = null)
    {
        if (source == null) return false;
        return predicate == null
            ? source.Any()
            : source.Any(predicate);
    }

So you can still do things like : myList.AnyNotNull(item=>item.AnswerToLife == 42); as you could with the regular .Any() but with the added null check

Note that with the C#6 way: myList?.Any() returns a bool? rather than a bool, which is the actual effect of propagating null

Thomas Mulder
  • 740
  • 10
  • 26
  • 1
    The problem with collection?.Any() is that is not transitive. When null, collection?.Any() == true is false, but collection?.Any() == false is also false. Moreover, !collection?.Any() == false is false too... – Jakub Szułakiewicz Jan 28 '20 at 14:39
8

This may help

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

public static bool IsNullOrEmpty<T>(this IEnumerable<T> enumerable)
{
    return enumerable?.Any() != true;
}
Hossein Narimani Rad
  • 31,361
  • 18
  • 86
  • 116
5

One can use this line for that verification when it's about reference (nullable) types and when no null item expected among the items

myCollection?.FirstOrDefault() == null
Adel Tabareh
  • 1,478
  • 14
  • 10
3

Jon Skeet's anwser (https://stackoverflow.com/a/28904021/8207463) has a good approach using Extension Method - Any() for NULL and EMPTY. BUT he´s validating the questions´owner in case for NOT NULL. So carefully change Jon´s approach to validate AS NULL to:

If (yourList?.Any() != true) 
{
     ..your code...
}

DO NOT use ( will not validate AS NULL):

If (yourList?.Any() == false) 
{
     ..your code...
}

You can also in case validating AS NOT NULL ( NOT tested just as example but without compiler error) do something like using predicate :

If (yourList?.Any(p => p.anyItem == null) == true) 
{
     ..your code...
}

https://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,8788153112b7ffd0

For which .NET version you can use it please check:

https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.any?view=netframework-4.8#moniker-applies-to

Sergio Rezende
  • 762
  • 8
  • 25
2

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.)

Community
  • 1
  • 1
Don Kirkby
  • 53,582
  • 27
  • 205
  • 286
2

I use Bool IsCollectionNullOrEmpty = !(Collection?.Any()??false);. Hope this helps.

Breakdown:

Collection?.Any() will return null if Collection is null, and false if Collection is empty.

Collection?.Any()??false will give us false if Collection is empty, and false if Collection is null.

Complement of that will give us IsEmptyOrNull.

1

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.

Keith Banner
  • 602
  • 1
  • 10
  • 15
1

I had the same problem and I solve it like :

    public bool HasMember(IEnumerable<TEntity> Dataset)
    {
        return Dataset != null && Dataset.Any(c=>c!=null);
    }

"c=>c!=null" will ignore all the null entities.

Hosein Djadidi
  • 198
  • 1
  • 3
  • 13
0

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() :)

caldera.sac
  • 4,918
  • 7
  • 37
  • 69
Mohit
  • 17
  • 1
0

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);
}
Basheer AL-MOMANI
  • 14,473
  • 9
  • 96
  • 92
0

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
  }
}
Shakeer Hussain
  • 2,230
  • 7
  • 29
  • 52
0

I use this one:

    public static bool IsNotEmpty(this ICollection elements)
    {
        return elements != null && elements.Count > 0;
    }

Ejem:

List<string> Things = null;
if (Things.IsNotEmpty())
{
    //replaces ->  if (Things != null && Things.Count > 0) 
}
Jhollman
  • 2,093
  • 24
  • 19
0

Since some resources are exhausted after one read, I thought why not combine the checks and the reads, instead of the traditional separate check, then read.

First we have one for the simpler check-for-null inline extension:

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();

Then we have the little more involved (well, at least the way I wrote it) check-for-null-and-empty inline extension:

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();

You can of course still call both without continuing the call chain. Also, I included the paramName, so that the caller may include an alternate name for the error if it's not "source" being checked, e.g. "nameof(target)".

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

my own extension method to check Not null and Any

0

Without custom helpers I recommend either ?.Any() ?? false or ?.Any() == true which are relatively concise and only need to specify the sequence once.


When I want to treat a missing collection like an empty one, I use the following extension method:

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

This function can be combined with all LINQ methods and foreach, not just .Any(), which is why I prefer it over the more specialized helper functions people are proposing here.

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
0

I use

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

The result will be null if no match, otherwise returns one of the objects

If you wanted the list, I believe leaving of First() or calling ToList() will provide the list or null.

Ron Chibnik
  • 89
  • 1
  • 5
0

it null will return true

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

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

            return true;
        }
   
    }

code here

Truong Mai Van
  • 137
  • 1
  • 4