LINQ Anti-Patterns: Multiple Enumeration & `Count() > 0` vs `Any()`
1Concept
Calling `.Count() > 0` iterates the entire sequence to count all items. `.Any()` halts immediately on the first item (O(1)). Multiple enumerations on IQueryable re-run heavy SQL queries against the database.
2Architecture Diagram
[ 1,000,000 Items in Database ] ├── .Count() > 0 ──> Iterates through all 1,000,000 items (Slow!) └── .Any() ──> Halts after item 1 (Instantaneous O(1) check!)
3Code Example
C# 13 & .NET 9
using System;
using System.Collections.Generic;
using System.Linq;
public class LinqPitfallsDemo
{
public static void Main()
{
IEnumerable<int> GetHeavyStream()
{
for (int i = 0; i < 1_000_000; i++)
{
if (i == 1) yield return i; // First item yielded immediately
}
}
var stream = GetHeavyStream();
// Optimized O(1) check:
bool hasElements = stream.Any();
Console.WriteLine($"Has Elements: {hasElements} (Evaluated instantly in O(1))");
}
}4Expected Output
Has Elements: True (Evaluated instantly in O(1))
5Key Takeaways
- ✓Always use `.Any()` instead of `.Count() > 0`.
- ✓Use `TryGetNonEnumeratedCount()` (.NET 6+) to check collection count without triggering enumeration.
- ✓Cache IEnumerable results with `.ToList()` before multi-pass consumption.