You didn’t seem to be the only one thinking that. The .NET Core implementation has an optimized version:
using (IEnumerator<TSource> e = source.GetEnumerator())
{
while (e.MoveNext())
{
TSource result = e.Current;
if (predicate(result))
{
while (e.MoveNext())
{
if (predicate(e.Current))
{
throw Error.MoreThanOneMatch();
}
}
return result;
}
}
}
So to answer your question: there doesn’t seem to be a ‘good’ reason, other than just a developer not thinking about optimizing this use case.