C# LINQ Any: Usage and Behavior
c# linq any: Learn how to use the LINQ Any method in C#, including syntax, predicate usage, performance tradeoffs, and how it differs from Count and Exists.
The C# LINQ Any method answers a simple question: does a collection contain at least one element? When called without arguments, it returns true if the sequence has any elements at all. When called with a predicate, it returns true if at least one element satisfies that condition.
var numbers = new List<int> { 1, 2, 3, 4, 5 }; bool hasElements = numbers.Any(); // true bool hasEven = numbers.Any(n => n % 2 == 0); // true
The method is defined on IEnumerable<T>, which means it works with arrays, List<T>, HashSet<T>, Dictionary<TKey, TValue> (via KeyValuePair enumeration), and any custom type that implements the interface. It is also available on IQueryable<T> through the Queryable class, which changes how it behaves with database-backed collections.
The key behavioral trait of Any() is short-circuiting. When a predicate is supplied, the method iterates the sequence until it finds the first matching element and then stops. It does not enumerate the entire collection unless no element matches. This is the primary reason Any() is often preferred over approaches that count all elements first.
Basic Syntax and Return Behavior
Any() has two overloads. The parameterless version checks whether the sequence is non-empty. The predicate version checks whether any element satisfies the condition.
public static bool Any<TSource>(this IEnumerable<TSource> source); public static bool Any<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate);
Both overloads return bool. The parameterless overload throws ArgumentNullException if source is null. The predicate overload throws the same exception if either source or predicate is null.
List<string> names = new List<string> { "Alice", "Bob", "Carol" }; bool anyNames = names.Any(); // true bool anyLongName = names.Any(n => n.Length > 4); // true bool anyShortName = names.Any(n => n.Length < 3); // false
The predicate is evaluated once per element, in order, until a match is found or the sequence is exhausted. Because of this, the order of elements in the source sequence matters for how quickly Any() returns. If the first element satisfies the predicate, the method returns after a single iteration step.
Using Any() with a Predicate
The predicate overload is where Any() becomes genuinely useful. It replaces manual loops that would otherwise check for the existence of a matching element.
var orders = new List<Order> { new Order { Id = 1, Status = "Pending" }, new Order { Id = 2, Status = "Shipped" }, new Order { Id = 3, Status = "Delivered" } }; bool hasPendingOrders = orders.Any(o => o.Status == "Pending");
Compare this with the manual loop equivalent:
bool HasPendingOrders(List<Order> orders) { foreach (var order in orders) { if (order.Status == "Pending") { return true; } } return false; }
The Any() version is shorter and expresses the intent directly. It also works uniformly across any IEnumerable<T>, whereas a manual loop requires writing the same iteration logic for every collection type and condition.
A common mistake is writing Where(...).Any() instead of Any(predicate). The former materializes an intermediate filtered sequence before checking for elements. The latter performs the check during iteration and avoids the intermediate allocation.
// Less efficient: builds a filtered sequence first bool result = orders.Where(o => o.Status == "Pending").Any(); // More efficient: checks during iteration bool result = orders.Any(o => o.Status == "Pending");
The difference matters when the source is large or when the predicate is expensive to evaluate.
Any() vs Count() > 0: Why the Difference Matters
A common pattern in older code is collection.Count() > 0 to check whether a collection has elements. The Count() LINQ method, when called on a plain IEnumerable<T>, enumerates the entire sequence to count every element. Any() stops at the first element.
// Enumerates the entire sequence bool hasItems = collection.Count() > 0; // Stops after the first element bool hasItems = collection.Any();
For an ICollection<T> or ICollection implementation, Count() uses the Count property directly and does not enumerate. But when the static type is IEnumerable<T>, the compiler cannot guarantee that optimization, so Count() may fall back to full enumeration.
The performance difference is most visible with lazy sequences, such as those produced by yield return, Select(), Where(), or file and network reads. With an infinite sequence, Count() would never return, while Any() returns true immediately.
IEnumerable<int> InfiniteSequence() { int i = 0; while (true) { yield return i++; } } bool hasAny = InfiniteSequence().Any(); // true, returns immediately // InfiniteSequence().Count() would never complete
The same reasoning applies to the predicate overload. Any(predicate) stops at the first match. Count(predicate) > 0 must examine every element before returning.
Any() vs Exists() on List<T>
List<T> has its own Exists(Predicate<T>) method that predates LINQ. It behaves similarly to Any(predicate) but is only available on List<T> and arrays (as a static method on Array).
var items = new List<int> { 10, 20, 30, 40 }; bool exists = items.Exists(x => x > 25); // true bool any = items.Any(x => x > 25); // true
The practical difference is type compatibility. Exists() requires a List<T> or T[]. Any() works with any IEnumerable<T>, including HashSet<T>, Dictionary<TKey, TValue>, LinkedList<T>, or a custom iterator. If the code already holds a List<T>, either method works, but Exists() is slightly more direct because it avoids the LINQ extension method dispatch. In practice, the difference is negligible unless the predicate is called millions of times.
Any() is the safer choice when the collection type may change later, because it does not couple the code to List<T> specifically.
How Any() Behaves with IQueryable
When the source is an IQueryable<T>, Any() is translated into a query expression by the underlying provider. With Entity Framework Core or LINQ to SQL, Any() typically becomes an EXISTS clause in SQL.
var hasActiveUsers = dbContext.Users.Any(u => u.IsActive);
This translates to something like:
SELECT CASE WHEN EXISTS ( SELECT 1 FROM Users WHERE IsActive = 1 ) THEN 1 ELSE 0 END
The database executes the EXISTS check and stops scanning rows as soon as a match is found. This is usually more efficient than loading all matching rows into memory and checking them client-side.
The same short-circuiting logic does not apply when the query is enumerated into memory first. Calling .ToList().Any() materializes the entire result set before the check runs. If the purpose is to determine whether any rows match, the query should remain as IQueryable until Any() is called.
// Materializes all matching rows into memory first bool result = dbContext.Users.Where(u => u.IsActive).ToList().Any(); // Lets the database perform the EXISTS check bool result = dbContext.Users.Any(u => u.IsActive);
The second version sends a more efficient query and avoids loading rows that are never used.
Edge Cases: Empty Collections and Null Elements
Any() returns false for an empty sequence in both overloads. This is the expected behavior: an empty collection has no elements, so it cannot contain any element that satisfies a predicate.
var empty = new List<int>(); bool any = empty.Any(); // false bool anyEven = empty.Any(n => n % 2 == 0); // false
Null elements inside the collection do not cause Any() to throw, provided the predicate handles them. The predicate receives each element as-is, including null references.
var items = new List<string?> { null, "hello", null }; bool hasNonNull = items.Any(s => s != null); // true bool hasSpecific = items.Any(s => s == "hello"); // true
A null predicate argument, however, throws ArgumentNullException. The same applies to a null source. This is consistent with the rest of the LINQ standard query operators.
One subtle behavior worth noting: Any() on a Dictionary<TKey, TValue> enumerates KeyValuePair<TKey, TValue> entries. To check whether a key exists, ContainsKey() is the correct method, not Any() with a predicate that inspects keys. ContainsKey() performs a hash lookup in O(1) time, while Any() would enumerate the entire dictionary in the worst case.
var lookup = new Dictionary<string, int> { ["alpha"] = 1, ["beta"] = 2 }; bool hasKey = lookup.ContainsKey("alpha"); // O(1) hash lookup bool hasKeyViaAny = lookup.Any(kv => kv.Key == "alpha"); // O(n) enumeration
This distinction matters in hot paths where the dictionary is large and the check is performed frequently. Choosing the right collection API for the operation is part of writing maintainable C# code that behaves predictably under load.