I found (roughly) this code in the Enumerable.Single
method while inspecting it with some decompiler:
foreach (TSource current in source)
{
if (predicate(current))
{
result = current;
num += 1L;
}
}
if (num > 1L)
{
throw Error.MoreThanOneMatch();
}
As you can see, it loops over all items before throwing. Why doesn't it break when num > 1
?
Agree, that it will be better from terms of performance (EDIT: if we are expecting more than one item matching our predicate, which we should not do):
foreach (TSource current in source)
{
if (predicate(current))
{
result = current;
num += 1L;
if (num > 1L)
throw Error.MoreThanOneMatch();
}
}
if (num == 0L)
throw Error.NoMatch();
return local;
Looks like they decided to make results analyzing more clear and separated it from enumerating source. But then I wonder why simple switch was not used:
switch((int)num)
{
case 0: throw Error.NoMatch();
case 1: return local;
default:
throw Error.MoreThanOneMatch();
}
Regarding to performance issues - I think it's assumed that Single
should be called when you are really expecting single result. Zero or more results is an exceptional path, which should not occur often (as any exception). So, it's more your program's logic error if source contain many items matching predicate.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With