dotnet / dotnet/dotnet-api-docs

Enumerable.Min<TSource>() documentation should mention null filtering behavior

Open
#7,923 5 comments 0 reactions 0 assignees View on GitHub
area-System.Linq doc-bug Pri3
Dominant language
C#
Stars
949
Forks
1.7k
Avg merge
3d 27m
Merged PRs (30d)
49

Description

In regards to `null`, the documentation states this:

> If `TSource` is a reference type and the source sequence is empty or contains only values that are `null`, this method returns `null`.

It also states:

> If type `TSource` implements [IComparable](https://docs.microsoft.com/en-us/dotnet/api/system.icomparable-1?view=net-6.0), the [Max(IEnumerable)](https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.max?view=net-6.0#system-linq-enumerable-max-1(system-collections-generic-ienumerable((-0)))) method uses that implementation to compare values. Otherwise, if type `TSource` implements [IComparable](https://docs.microsoft.com/en-us/dotnet/api/system.icomparable?view=net-6.0), that implementation is used to compare values.

This leads me to believe that the minimum value will be calculated purely based on the output of `IComparable.Compare(T, T)`. That is, the output of `.Min()` would be the same as `.OrderBy(x => x).First()` and the output of `.Max()` would be the same as `.OrderBy(x => x).Last()`. Or that if `Comparer.Default.Compare(a, b) < 0`, then the output of `new[] { a, b, }.Min()` would be `a`. However, I found the following behavior instead:

```csharp
Console.WriteLine($"Comparer.Default.Compare(null, \"a\") == {Comparer.Default.Compare(null, "a")}");
Console.WriteLine($"new[]{{ null, \"a\", }}.OrderBy(x => x).First() == {new[] { null, "a", }.OrderBy(x => x).First()}");
Console.WriteLine($"new[]{{ null, \"a\", }}.Min() == {new[] { null, "a", }.Min()}");
```

with output:

```
Comparer.Default.Compare(null, "a") == -1
new[]{ null, "a", }.OrderBy(x => x).First() ==
new[]{ null, "a", }.Min() == a
```

By experiencing this and examining [the](https://github.com/dotnet/runtime/blob/main/src/libraries/System.Linq/src/System/Linq/Min.cs#L614) [source](https://github.com/dotnet/runtime/blob/e3ecc8372630f22011815d64099598e30bcb43a7/src/libraries/System.Linq/src/System/Linq/Min.cs#L614), I know that `.Min()` and `.Max()` implicitly filter out any values equal to `null` as the first step (including nullable value types which box to `null`). However, this is not obvious from the documentation.

May you please alter the documentation to document this behavior?

Thanks!

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.