Search code examples
c#listextension-methodsienumerableisnullorempty

IEnumerable vs Ilist - IsNullOrEmpty extension method


I have a custom collection IList<user>as users. When I tried to check whether users is null or empty, I did not get any intelligence help(like IsNullOrEmpty) so I wrote the below extension method

public static bool IsNullOrEmpty<T>(this IEnumerable<T> source)
{
        if (source.IsNullOrEmpty())
        {
            return true;
        }

        return false;
}

To my surprise, I found that IEnumerable<T> has IsNullOrEmpty().

As per my knowledge IList extends ICollection which again extend IEnumerable, if that is the case then IList should support IsNullOrEmpty.

Please correct where I am wrong.


Solution

  • IEnumerable<T> has not an IsNullOrEmpty method, it is the extension that you have written above. If you call it you get a StackOverflowException.

    You could implement it in this way:

    public static bool IsNullOrEmpty<T>(this IEnumerable<T> source)
    {
        return source == null || !source.Any();
    }
    

    But it's important to note that this method is not so helpful and can even improve for the worse. Because Enumerable.Any will "consume" the query. So if it's not an in-memory collection it has to call GetEnumerator and start enumerating it so check if there is at least one item. Sometimes the object will be diosposed in case it was enumerated (like in File.ReadLines in .NET <= 4) which willl cause an ObjectDisposedException if you try to consume it later again.

    Another example when this method has unwanted side-effects is when the sequence is a query which filters(...Where(x => Compute(x, random.Next()))). This query might yield different results everytime. To quote Marc Gravell's comment: "IEnumerable should not be assumed to be repeatable".

    In Linq-To-Sql or Linq-To-Entities you'd call the database on every IsNullOrEmpty call.