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