Phase 12 of 30 · Topic 12.5

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.