Description
#53528 mentions the issues when these methods change their behavior "unpredictably" based on the predicate type. I think the behavior changing based on the source sequence type is no more predictable:
if (!e.MoveNext())
{
if (default(TSource) is null)
{
return default;
}
else
{
ThrowHelper.ThrowNoElementsException();
}
}
It is typical for the keys of a collection (Dictionary, HashSet, etc.) to be required to not be null, but never before were null elements discriminated in Enumerable extensions like this. How do I distinguish between
and
using these methods? Did these ifs get in because the *OrDefault versions did not get implemented and this is the compomise? I do not think this is convenient or expected at all. What are users supposed to do in their generic methods that call MinBy, replicate this logic (checking default(TSource)) every single time to work around this behavior?
Reproduction Steps
Call Enumerable.MinBy on a reference type, e.g.:
new string[] {}.MinBy(x=>x)
Expected behavior
a new InvalidOperationException(SR.NoElements) is thrown like for every other method that expects at least a single element, e.g. Single, Min, Max, First.
Actual behavior
null is returned
Regression?
Not a regression
Known Workarounds
Fuff about with ifs (which is not the intended idea of LINQ one would think) or write own extensions methods (which is more difficult now because the problematic framework ones took away the reasonable name). MoreLinq works around this problem by returning an enumerable from Min/MaxBy, which i think is an entirely reasonable approach.
Configuration
.NET SDK 6.0.100
Other information
No response
Description
#53528 mentions the issues when these methods change their behavior "unpredictably" based on the predicate type. I think the behavior changing based on the source sequence type is no more predictable:
It is typical for the keys of a collection (Dictionary, HashSet, etc.) to be required to not be null, but never before were null elements discriminated in Enumerable extensions like this. How do I distinguish between
and
using these methods? Did these ifs get in because the *OrDefault versions did not get implemented and this is the compomise? I do not think this is convenient or expected at all. What are users supposed to do in their generic methods that call MinBy, replicate this logic (checking
default(TSource)) every single time to work around this behavior?Reproduction Steps
Call Enumerable.MinBy on a reference type, e.g.:
Expected behavior
a
new InvalidOperationException(SR.NoElements)is thrown like for every other method that expects at least a single element, e.g. Single, Min, Max, First.Actual behavior
null is returned
Regression?
Not a regression
Known Workarounds
Fuff about with ifs (which is not the intended idea of LINQ one would think) or write own extensions methods (which is more difficult now because the problematic framework ones took away the reasonable name). MoreLinq works around this problem by returning an enumerable from Min/MaxBy, which i think is an entirely reasonable approach.
Configuration
.NET SDK 6.0.100
Other information
No response