-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[API Proposal]: Enumerable.Reverse<T>(T[]) #107723
Comments
Tagging subscribers to this area: @dotnet/area-system-linq |
Sounds reasonable. I'm guessing this is the only (Linq) location where such a break was encountered when prototyping first-class spans? |
Yes. Other notes: An alternative would be applying The same breaking change exists for people on .NET Framework / netstandard and using the System.Memory NuGet package and updating to C# 14. I'm not sure how we can tackle that. Perhaps users can define their own |
What's the downside to this? Is it just that if I have an array, calling |
Yes, I don't think there are any other downsides. I just haven't thought this workaround through more previously. The usual effect of ORPA making the overload un-callable does not apply here since both |
I thought |
Ah, thanks, you're right, I forgot about that aspect. Disregard the ORPA alternative then. |
@Joe4evr is correct. ORPA is not an option here. |
Yes, that is my assumption on what they'll need to do. I've suggested to @Sergio0694 that he should add this to polysharp, and appropriately type forward in the negative case. Since this is called by user code, if the type forward isn't there, anyone attempting to support downlevel will need to be careful, or risk creating a missingmethodexception scenario. |
namespace System.Linq;
public static class Enumerable
{
public static IEnumerable<TSource> Reverse<TSource>(this TSource[] source);
} |
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 betweenvoid MemoryExtensions.Reverse<T>(this Span<T>)
andIEnumerable<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 forarray.Reverse()
, is worth the tradeoff.Elaborating on the break: today,
array.Reverse()
binds toEnumerable.Reverse<T>(IEnumerable<T>)
, andMemoryExtensions.Reverse(Span<T>)
isn't applicable. In C# 14, this changes; both of these methods are applicable in extension form, and theSpan<T>
version is preferred overIEnumerable<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 ofReverse
for some reason, is a behavior break). By introducingEnumerable.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-basedEnumerable
methods.API Proposal
API Usage
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.
The text was updated successfully, but these errors were encountered: