Enumerable.Last () Throws InvalidOperationException "The sequence does not contain a matching element"
In the pre-sorted, List<int>
I'm going to find the last element that meets the condition, for example int lastScore = list.Last(x => x < 100)
. If not in the list of elements (elements), satisfying this condition with an error message is issued InvalidOperationException
: Sequence contains no matching element
. This also happens with list.First(...)
.
I've even tried to make lastScore
nullable to no avail.
Catch the exception and manually assign lastScore
to the null
only way out?
Use FirstOrDefault
or LastOrDefault
to get null
if there is no match if you are working with reference types. These methods will return the default for value types.
I would probably just catch the Exception at the closest point of use.
This is because LastOrDefault/FirstOrDefault
over IEnumerable<int>
will return 0 (the default for int
) which can be a "valid" value - this depends on the actual context and the rules defined. Converting the sequence to IEnumerable<int?>
would allow the previous methods to return null
, which seems like more work than it costs.
If you need to use lastScore
for future reference, consider:
int? lastScore; /* Using a Nullable<int> to be able to detect "not found" */
try {
lastScore = list.Last(x => x < 100); /* int -> int? OK */
} catch (InvalidOperationException) {
lastScore = null; /* If 0 see LastOrDefault as suggested;
otherwise react appropriately with a sentinel/flag/etc */
}
if (lastScore.HasValue) {
/* Found value meeting conditions */
}
Or, if you can drop the case where it was not found, consider:
try {
var lastScore = list.Last(x => x < 100);
/* Do something small/immediate that won't throw
an InvalidOperationException, or wrap it in it own catch */
return lastScore * bonus;
} catch (InvalidOperationException) {
/* Do something else entirely, lastScore is never available */
return -1;
}