Skip to content

Add MemoryExtensions.Min/Max#128306

Open
manandre wants to merge 1 commit into
dotnet:mainfrom
manandre:span-min-max
Open

Add MemoryExtensions.Min/Max#128306
manandre wants to merge 1 commit into
dotnet:mainfrom
manandre:span-min-max

Conversation

@manandre
Copy link
Copy Markdown
Contributor

This pull request adds new Min and Max extension methods for ReadOnlySpan<T> to the System.Memory library, allowing users to efficiently find the minimum and maximum values in a span, optionally using a custom comparer. Comprehensive unit tests are included to verify correct behavior for various data types and edge cases.

New Min and Max methods for ReadOnlySpan<T>:

  • Added Min<T> and Max<T> extension methods to MemoryExtensions for ReadOnlySpan<T>, supporting both default and custom comparers, and handling nullable and reference types gracefully. These methods throw an exception on empty spans of non-nullable value types and return null for empty spans of reference or nullable types. [1] [2]

Unit tests:

  • Introduced comprehensive tests in ReadOnlySpan/MinMax.cs to cover empty spans, all-null values, custom comparers, and typical scenarios for both value and reference types.
  • Registered the new test file in the project file System.Memory.Tests.csproj to ensure the tests are run as part of the test suite.

Fixes #127083

Copilot AI review requested due to automatic review settings May 17, 2026 21:55
@dotnet-policy-service dotnet-policy-service Bot added the community-contribution Indicates that the PR has been added by a community member label May 17, 2026
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/area-system-memory
See info in area-owners.md if you want to be subscribed.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds Min and Max extension methods on ReadOnlySpan<T> (with optional IComparer<T>), mirroring LINQ's Enumerable.Min/Max semantics for spans. Includes ref assembly updates and tests.

Changes:

  • New Min/Max ReadOnlySpan extension methods with empty-span and null-element handling.
  • Reference assembly exposes the four new API overloads.
  • New test file covering empty, all-null, mixed-null, default comparer, and custom comparer scenarios.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 8 comments.

File Description
src/libraries/System.Private.CoreLib/src/System/MemoryExtensions.cs Implements Min/Max with a generic comparer fast path and null-skipping inner core.
src/libraries/System.Memory/ref/System.Memory.cs Adds public surface for the four new overloads.
src/libraries/System.Memory/tests/System.Memory.Tests.csproj Includes the new test file.
src/libraries/System.Memory/tests/ReadOnlySpan/MinMax.cs Tests for empty/null/normal/custom-comparer behaviors.

return default;
}

ThrowHelper.ThrowInvalidOperationException();
/// <param name="comparer">The <see cref="IComparer{T}"/> to compare values.</param>
/// <returns>The minimum value in the span.</returns>
/// <exception cref="InvalidOperationException"><paramref name="span"/> is empty and <typeparamref name="T"/> is a non-nullable value type.</exception>
public static T? Min<T>(this ReadOnlySpan<T> span, IComparer<T> comparer)
Comment on lines +4367 to +4368
T next = span[i];
if (next is not null && comparer.Compare(next, value) < 0)
Comment on lines +4350 to +4351
static T? MinCore<TComparer>(ReadOnlySpan<T> span, TComparer comparer)
where TComparer : IComparer<T>
Comment on lines +4324 to +4334
Min(span, comparer: null!);

/// <summary>
/// Returns the minimum value in the span.
/// </summary>
/// <typeparam name="T">The type of the elements in the span.</typeparam>
/// <param name="span">The span of values to determine the minimum value of.</param>
/// <param name="comparer">The <see cref="IComparer{T}"/> to compare values.</param>
/// <returns>The minimum value in the span.</returns>
/// <exception cref="InvalidOperationException"><paramref name="span"/> is empty and <typeparamref name="T"/> is a non-nullable value type.</exception>
public static T? Min<T>(this ReadOnlySpan<T> span, IComparer<T> comparer)
Comment on lines +77 to +80
public static void MinMax_CustomComparer_IsUsed()
{
ReadOnlySpan<int> ints = new int[] { 4, -1, 7, 2 };
IComparer<int> reverse = Comparer<int>.Create((left, right) => right.CompareTo(left));
Comment on lines +234 to 237
public static T? Max<T>(this System.ReadOnlySpan<T> span, System.Collections.Generic.IComparer<T> comparer) { throw null; }
public static T? Min<T>(this System.ReadOnlySpan<T> span) { throw null; }
public static T? Min<T>(this System.ReadOnlySpan<T> span, System.Collections.Generic.IComparer<T> comparer) { throw null; }
[System.Runtime.CompilerServices.OverloadResolutionPriorityAttribute(-1)]
/// <typeparam name="T">The type of the elements in the span.</typeparam>
/// <param name="span">The span of values to determine the minimum value of.</param>
/// <returns>The minimum value in the span.</returns>
/// <exception cref="InvalidOperationException"><paramref name="span"/> is empty and <typeparamref name="T"/> is a non-nullable value type.</exception>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-System.Memory community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[API Proposal]: MemoryExtensions.Min/Max

2 participants