C# Language First, FirstOrDefault, Last, LastOrDefault, Single, and SingleOrDefault


Example

All six methods return a single value of the sequence type, and can be called with or without a predicate.

Depending on the number of elements that match the predicate or, if no predicate is supplied, the number of elements in the source sequence, they behave as follows:

First()

  • Returns the first element of a sequence, or the first element matching the provided predicate.
  • If the sequence contains no elements, an InvalidOperationException is thrown with the message: "Sequence contains no elements".
  • If the sequence contains no elements matching the provided predicate, an InvalidOperationException is thrown with the message "Sequence contains no matching element".

Example

// Returns "a":
new[] { "a" }.First();

// Returns "a":
new[] { "a", "b" }.First();

// Returns "b":
new[] { "a", "b" }.First(x => x.Equals("b"));

// Returns "ba":
new[] { "ba", "be" }.First(x => x.Contains("b"));

// Throws InvalidOperationException:
new[] { "ca", "ce" }.First(x => x.Contains("b"));

// Throws InvalidOperationException:
new string[0].First();

Live Demo on .NET Fiddle

FirstOrDefault()

  • Returns the first element of a sequence, or the first element matching the provided predicate.
  • If the sequence contains no elements, or no elements matching the provided predicate, returns the default value of the sequence type using default(T).

Example

// Returns "a":
new[] { "a" }.FirstOrDefault();

// Returns "a":
new[] { "a", "b" }.FirstOrDefault();

// Returns "b":
new[] { "a", "b" }.FirstOrDefault(x => x.Equals("b"));

// Returns "ba":
new[] { "ba", "be" }.FirstOrDefault(x => x.Contains("b"));

// Returns null:
new[] { "ca", "ce" }.FirstOrDefault(x => x.Contains("b"));

// Returns null:
new string[0].FirstOrDefault();

Live Demo on .NET Fiddle

Last()

  • Returns the last element of a sequence, or the last element matching the provided predicate.
  • If the sequence contains no elements, an InvalidOperationException is thrown with the message "Sequence contains no elements."
  • If the sequence contains no elements matching the provided predicate, an InvalidOperationException is thrown with the message "Sequence contains no matching element".

Example

// Returns "a":
new[] { "a" }.Last();

// Returns "b":
new[] { "a", "b" }.Last();

// Returns "a":
new[] { "a", "b" }.Last(x => x.Equals("a"));

// Returns "be":
new[] { "ba", "be" }.Last(x => x.Contains("b"));

// Throws InvalidOperationException:
new[] { "ca", "ce" }.Last(x => x.Contains("b"));

// Throws InvalidOperationException:
new string[0].Last(); 

LastOrDefault()

  • Returns the last element of a sequence, or the last element matching the provided predicate.
  • If the sequence contains no elements, or no elements matching the provided predicate, returns the default value of the sequence type using default(T).

Example

// Returns "a":
new[] { "a" }.LastOrDefault();

// Returns "b":
new[] { "a", "b" }.LastOrDefault();

// Returns "a":
new[] { "a", "b" }.LastOrDefault(x => x.Equals("a"));

 // Returns "be":
new[] { "ba", "be" }.LastOrDefault(x => x.Contains("b"));

// Returns null:
new[] { "ca", "ce" }.LastOrDefault(x => x.Contains("b")); 

// Returns null:
new string[0].LastOrDefault();

Single()

  • If the sequence contains exactly one element, or exactly one element matching the provided predicate, that element is returned.
  • If the sequence contains no elements, or no elements matching the provided predicate, an InvalidOperationException is thrown with the message "Sequence contains no elements".
  • If the sequence contains more than one element, or more than one element matching the provided predicate, an InvalidOperationException is thrown with the message "Sequence contains more than one element".
  • Note: in order to evaluate whether the sequence contains exactly one element, at most two elements has to be enumerated.

Example

// Returns "a":
new[] { "a" }.Single();

// Throws InvalidOperationException because sequence contains more than one element:
new[] { "a", "b" }.Single();

// Returns "b":
new[] { "a", "b" }.Single(x => x.Equals("b"));

// Throws InvalidOperationException:
new[] { "a", "b" }.Single(x => x.Equals("c"));

// Throws InvalidOperationException:
new string[0].Single(); 

// Throws InvalidOperationException because sequence contains more than one element:
new[] { "a", "a" }.Single();

SingleOrDefault()

  • If the sequence contains exactly one element, or exactly one element matching the provided predicate, that element is returned.
  • If the sequence contains no elements, or no elements matching the provided predicate, default(T) is returned.
  • If the sequence contains more than one element, or more than one element matching the provided predicate, an InvalidOperationException is thrown with the message "Sequence contains more than one element".
  • If the sequence contains no elements matching the provided predicate, returns the default value of the sequence type using default(T).
  • Note: in order to evaluate whether the sequence contains exactly one element, at most two elements has to be enumerated.

Example

// Returns "a":
new[] { "a" }.SingleOrDefault();

// returns "a"
new[] { "a", "b" }.SingleOrDefault(x => x == "a"); 

// Returns null:
new[] { "a", "b" }.SingleOrDefault(x => x == "c");

// Throws InvalidOperationException:
new[] { "a", "a" }.SingleOrDefault(x => x == "a");

// Throws InvalidOperationException:
new[] { "a", "b" }.SingleOrDefault();

// Returns null:
new string[0].SingleOrDefault();

Recommendations

  • Although you can use FirstOrDefault, LastOrDefault or SingleOrDefault to check whether a sequence contains any items, Any or Count are more reliable. This is because a return value of default(T) from one of these three methods doesn't prove that the sequence is empty, as the value of the first / last / single element of the sequence could equally be default(T)

  • Decide on which methods fits your code's purpose the most. For instance, use Single only if you must ensure that there is a single item in the collection matching your predicate — otherwise use First; as Single throw an exception if the sequence has more than one matching element. This of course applies to the "*OrDefault"-counterparts as well.

  • Regarding efficiency: Although it's often appropriate to ensure that there is only one item (Single) or, either only one or zero (SingleOrDefault) items, returned by a query, both of these methods require more, and often the entirety, of the collection to be examined to ensure there in no second match to the query. This is unlike the behavior of, for example, the First method, which can be satisfied after finding the first match.