Codectionary / Developer documentation / C#

LINQ Element & Quantifier Operators

Element operators retrieve a single item from a sequence: First()/FirstOrDefault() for the first match, Single()/SingleOrDefault() for exactly one match, with 'OrDefault' variants returning a default value instead of throwing when nothing matches. Quantifier operators return a bool describing the sequence as a whole: Any() checks if at least one element matches, and All() checks if every element matches.

Read the syntax

First requires at least one match; FirstOrDefault returns a type’s default when none matches. Single requires exactly one match and also throws if more than one matches.

Any checks whether some element matches, All whether every element matches, and Contains checks for an equal value. Choose based on the question and expected number of matches.

Syntax

collection.First(predicate)\ncollection.Any(predicate)

Examples

First and FirstOrDefault

Retrieving the first matching element, with and without risking an exception.

List<int> numbers = new List<int> { 1, 3, 5, 8, 9 };

int firstEven = numbers.First(n => n % 2 == 0);
Console.WriteLine(firstEven);  // 8

int firstNegative = numbers.FirstOrDefault(n => n < 0);
Console.WriteLine(firstNegative);  // 0 (default for int) - no exception, no match found
  1. Retrieving the first matching element, with and without risking an exception.
  2. First requires at least one match; FirstOrDefault returns a type’s default when none matches. Single requires exactly one match and also throws if more than one matches.
  3. First finds 8 as the first even value. No number is negative, so FirstOrDefault returns 0, the default int; that does not prove zero was present.

Single and SingleOrDefault

Expecting exactly one match - throws if there are zero or more than one.

List<string> names = new List<string> { "John", "Zain", "Jamal" };

string zain = names.Single(n => n == "Zain");
Console.WriteLine(zain);  // Zain

// names.Single(n => n.StartsWith("Ja"));  // fine, only Jamal matches
// names.Single(n => n.Length == 4);        // throws! Both "John" and "Zain" match
  1. Expecting exactly one match - throws if there are zero or more than one.
  2. First requires at least one match; FirstOrDefault returns a type’s default when none matches. Single requires exactly one match and also throws if more than one matches.
  3. Exactly one name equals Zain, so Single returns it. The commented length-four query would throw because John and Zain both match.

Any and All

Checking whether some or every element satisfies a condition.

List<int> numbers = new List<int> { 2, 4, 6, 8 };

bool hasOdd = numbers.Any(n => n % 2 != 0);
Console.WriteLine(hasOdd);  // false

bool allEven = numbers.All(n => n % 2 == 0);
Console.WriteLine(allEven);  // true

bool isEmpty = !numbers.Any();  // Any() with no predicate checks for any elements at all
Console.WriteLine(isEmpty);  // false
  1. Checking whether some or every element satisfies a condition.
  2. First requires at least one match; FirstOrDefault returns a type’s default when none matches. Single requires exactly one match and also throws if more than one matches.
  3. No odd number exists, every number is even, and the list is nonempty. The three bool values print False, True and False.

Contains

Checking whether a sequence contains a specific value.

List<string> names = new List<string> { "John", "Zain", "Jamal" };

Console.WriteLine(names.Contains("Zain"));    // true
Console.WriteLine(names.Contains("Amir"));    // false
  1. Checking whether a sequence contains a specific value.
  2. First requires at least one match; FirstOrDefault returns a type’s default when none matches. Single requires exactly one match and also throws if more than one matches.
  3. Contains finds Zain and does not find Amir, printing True and False. Its equality behavior follows the collection’s comparer.

Best practices

  • Use the "OrDefault" variants (FirstOrDefault, SingleOrDefault) when a missing match is a normal, expected outcome rather than a bug
  • Use Single() specifically when exactly one match is a hard requirement - it deliberately throws if that assumption is ever violated, surfacing bugs early
  • Use Any() instead of Count() > 0 to check for existence - Any() can stop as soon as it finds one match, while Count() must potentially scan the whole sequence
  • Check for null (or use a pattern like ?? defaultValue) after FirstOrDefault()/SingleOrDefault() on reference types, since the default is null

Runtime & versions

.NET runtime. Feature availability depends on the language and runtime version used by your project; consult the official reference below.

C# language reference

Specifications & further reading