How to check if IEnumerable is null or empty?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Checking whether an IEnumerable is null or empty sounds simple, but there is one detail that matters: IEnumerable may represent a lazy sequence, not a materialized collection. That means a null-or-empty check can sometimes trigger enumeration.
The most common practical answer is source == null || !source.Any(). It is concise, readable, and efficient for most cases because Any() stops as soon as it finds the first element.
The Basic Check
For an IEnumerable<T>, the usual pattern is:
This works because:
- the null check protects against
NullReferenceException - '
Any()returns quickly once it sees the first item' - the code reads almost like plain English
For most application code, this is all you need.
A Reusable Extension Method
If you perform this check often, wrap it in an extension method:
Usage:
This improves readability, especially in business logic where the null-or-empty concept appears frequently.
Be Aware of Lazy Sequences
IEnumerable<T> is not always a list. It might be a LINQ query, a generator, or a streaming sequence.
That means Any() may execute part of the query. For example:
The query does not run until Any() is called. Then it starts enumerating until it finds a matching item or reaches the end.
That behavior is usually fine, but it is important to remember that checking emptiness can still have cost or side effects if the sequence is expensive or stateful.
Fast Path for Real Collections
Sometimes you want to avoid even a single-element enumeration when the source is already a collection with a count.
This is a nice refinement because it uses Count directly for collections and falls back to Any() for everything else.
When Not to Check Twice
A common anti-pattern is:
For a lazy sequence, this can enumerate twice: once for Any() and once for foreach. If the sequence is expensive, consider materializing it first or restructuring the code.
That is one reason IEnumerable<T> is different from List<T>. The abstraction is powerful, but it hides whether the sequence is cached or recomputed.
Common Pitfalls
The biggest mistake is calling Any() without a null check. Any() itself does not handle null sources.
Another common issue is assuming every IEnumerable<T> is a cheap in-memory collection. Some are queries, streams, or one-shot iterators.
A third problem is checking Any() and then enumerating again without realizing the sequence may run twice.
Summary
- The usual check is
source == null || !source.Any(). - '
Any()is efficient because it stops after the first item.' - An extension method can make the pattern easier to reuse.
- For real collections, a
Countfast path can avoid enumeration. - Be careful with lazy sequences, because even an emptiness check may execute part of the query.

