When working with collections or LINQ queries in C#, you’ll often find yourself checking whether a list has any items. Two common approaches are:
somethingList.Count() == 0
and
!somethingList.Any()
At first glance, both seem to do the same job. But under the hood, they behave very differently—especially when performance matters.
Count() — What Actually Happens?
When you call Count() on a collection, its behavior depends on the type of collection:
1. List, Array, or ICollection
2. IEnumerable or LINQ Query
Count() is a method, not a property.
Must iterate through the entire sequence.
This becomes an O(n) operation.
EF Core Scenario
Count() translates to:
SELECT COUNT(*) FROM Table
This forces the database to scan the entire table.
Any() — Why It's Faster
Any() simply checks whether at least one element exists.
EF Core Translation
SELECT TOP(1) 1 FROM Table
A much lighter query that avoids a full table scan.
Performance Comparison
| Scenario | Count() | Any() |
|---|
| List / Array (ICollection) | Fast (O(1)) | Fast (O(1)) |
| LINQ over IEnumerable | Slow (O(n)) | Fast (O(1)) |
| EF Core / Database | Expensive – generates COUNT(*) | Efficient – generates TOP(1) |
| Checking for empty collection | Not recommended | Best approach |
When Should You Use What?
Use Any() when checking if a collection has at least one item
Cleanest and most efficient way:
if (!orders.Any()) { ... }
Use Count() when you actually need the number of items
Example:
if (orders.Count() > 10) { ... }
Do NOT use Count() just to check emptiness
Especially when working with:
LINQ queries
EF Core
Large datasets
Streaming data
Real-World Example
Inefficient (forces DB to count all rows)
if (await context.Users.CountAsync() == 0)
{
// ...
}
Efficient (stops when it finds the first row)
if (!await context.Users.AnyAsync())
{
// ...
}
Simple Rule to Remember
Even though Count() and Any() look similar, the performance difference becomes significant when dealing with large collections or database queries.