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:
predicate
.InvalidOperationException
is thrown with the message: "Sequence contains no elements".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();
predicate
.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();
predicate
.InvalidOperationException
is thrown with the message "Sequence contains no elements."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();
predicate
.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();
predicate
, that element is returned.predicate
, an InvalidOperationException
is thrown with the message "Sequence contains no elements".predicate
, an InvalidOperationException
is thrown with the message "Sequence contains more than one element".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();
predicate
, that element is returned.predicate
, default(T)
is returned.predicate
, an InvalidOperationException
is thrown with the message "Sequence contains more than one element".predicate
, returns the default value of the sequence type using default(T)
.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();
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.