Skip to content

[API Proposal]: Enumerable.Reverse<T>(T[]) #107723

Description

@333fred

Background and motivation

The BCL has long resisted adding new array-based enumerable implementations, and with good reason; however, C# 14 is going to introduce a new feature, first-class spans, which unfortunately changes what array.Reverse() means between void MemoryExtensions.Reverse<T>(this Span<T>) and IEnumerable<T> Enumerable.Reverse<T>(this IEnumerable<T>). Overall, the benefits of this new feature will pretty significantly benefit the BCL by reducing the number of overloads of various things that are necessary; in talking with @stephentoub, we believe that adding an array-based overload, only for this specific case, and only to ensure source-compatibility for array.Reverse(), is worth the tradeoff.

Elaborating on the break: today, array.Reverse() binds to Enumerable.Reverse<T>(IEnumerable<T>), and MemoryExtensions.Reverse(Span<T>) isn't applicable. In C# 14, this changes; both of these methods are applicable in extension form, and the Span<T> version is preferred over IEnumerable<T>. This means the behavior changes from "return a new stream, reversed from the input stream", to "in-place reverse the array, and return nothing". This is almost certainly a source-breaking change (or, for the person that ignored the result of Reverse for some reason, is a behavior break). By introducing Enumerable.Reverse<T>(T[]), that method will be the most-specific overload among the 3 applicable methods, and existing behavior will be preserved.

Important note: this does not mean that we are reopening the door for array-based Enumerable extensions overall. We are specifically looking at this method to fix a source-breaking change in C# 14. This proposal should not be used to justify further expansion of array-based Enumerable methods.

API Proposal

namespace System.Linq;

public static class Enumerable
{
    public static IEnumerable<TSource> Reverse<TSource>(this T[] source);
}

API Usage

using System;
using System.Linq;

int[] l = [1, 2, 3];

foreach (var v in l.Reverse())
    Console.WriteLine(v);

Alternative Designs

No response

Risks

This is a fairly low-risk API, so long as we don't go using it to justify further array-based Enumerable overloads.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions