100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
C#

Any, All, and Contains

Master LINQ's boolean-returning quantifier operators — Any, All, and Contains — and how their short-circuiting behavior makes them efficient existence checks.

Aggregation and SetsBeginner8 min readJul 10, 2026
Analogies

Boolean Quantifiers in LINQ

Any(), All(), and Contains() are LINQ's boolean-returning operators, each answering a different existence question about a sequence: Any() asks 'does at least one element satisfy this?', All() asks 'do every one of the elements satisfy this?', and Contains() asks 'does this exact value appear in the sequence?'. All three short-circuit — they stop enumerating the moment the answer is determined, which is a major performance advantage over materializing a filtered list just to check Count() > 0.

🏏

Cricket analogy: A fielding captain scanning the scoreboard just needs to know 'has any bowler taken a five-wicket haul today', and stops checking the instant they spot one, just like Any() halts as soon as it finds a match.

Any vs Count() > 0, and All's Empty-Sequence Quirk

A very common anti-pattern is writing collection.Count() > 0 or collection.Count > 0 to check for emptiness — Any() is preferable because it stops at the first element instead of counting everything, which matters a lot for IQueryable sources translated to SQL (Any() becomes an efficient EXISTS query, while Count() > 0 becomes a full COUNT(*)). All() has a subtle quirk worth memorizing: All() on an empty sequence always returns true — this is called 'vacuous truth', because there are no elements to violate the condition, which trips people up who expect All() to require at least one element to exist.

🏏

Cricket analogy: Asking 'is there any spinner in today's XI' only requires spotting one, not counting the whole bowling attack, just as Any() beats Count() > 0 by stopping at the first match instead of tallying everyone.

Contains and Custom Equality

Contains(value) checks whether a sequence includes an element equal to value, using EqualityComparer<T>.Default unless you supply an IEqualityComparer<T> explicitly — for reference types without an overridden Equals(), this means it checks reference equality, which surprises people expecting value-based comparison on custom classes. Contains() is especially powerful combined with a HashSet<T> as the source, since HashSet<T>.Contains() is O(1) average case, versus O(n) for List<T>.Contains(), which matters when you're checking membership repeatedly inside a loop, such as filtering one list against another with Where(x => allowedIds.Contains(x.Id)).

🏏

Cricket analogy: Checking if a specific player's jersey number exists on today's team sheet by comparing shirt numbers (a value), not by comparing physical shirts (references), mirrors how Contains() needs proper Equals() overrides to compare custom objects by value.

csharp
var products = new List<Product>
{
    new Product { Id = 1, Name = "Widget", Price = 9.99m, InStock = true },
    new Product { Id = 2, Name = "Gadget", Price = 29.99m, InStock = false },
};

// Any short-circuits on the first match
bool hasOutOfStock = products.Any(p => !p.InStock); // true

// All returns true vacuously if the sequence is empty
bool allExpensive = new List<Product>().All(p => p.Price > 100); // true!

// Contains uses default equality unless a comparer is supplied
var allowedIds = new HashSet<int> { 1, 5, 9 };
var allowed = products.Where(p => allowedIds.Contains(p.Id)).ToList();

// Prefer Any() over Count() > 0 for existence checks (especially on IQueryable)
bool hasAny = products.Any();           // translates to SQL EXISTS
bool hasAnySlow = products.Count() > 0;  // translates to SQL COUNT(*)

All() returns true for an empty sequence — this is mathematically correct 'vacuous truth' but frequently unintended. If your logic really means 'there must be at least one element, and all of them must satisfy X', combine it explicitly: source.Any() && source.All(predicate).

When checking membership against IQueryable<T> backed by a database (e.g., Entity Framework), Any(predicate) is translated into an efficient SQL EXISTS(...) subquery, while Count(predicate) > 0 forces the database to compute a full COUNT — always prefer Any() for pure existence checks.

  • Any() checks 'does at least one element match' and short-circuits on the first hit.
  • All() checks 'do all elements match' and returns true (vacuous truth) on an empty sequence.
  • Contains() checks for an exact value match using EqualityComparer<T>.Default unless overridden.
  • Prefer Any() over Count() > 0 — both for readability and for query-translation efficiency.
  • HashSet<T>.Contains() is O(1) average case, much faster than List<T>.Contains()'s O(n) for repeated lookups.
  • Custom reference types need Equals()/GetHashCode() overrides for Contains() to compare by value.
  • Combine Any() && All() when you need 'non-empty AND every element satisfies X'.

Practice what you learned

Was this page helpful?

Topics covered

#LINQStudyNotes#MicrosoftTechnologies#AnyAllAndContains#Any#Contains#Boolean#Quantifiers#StudyNotes#SkillVeris#ExamPrep