Skip to content

Conversation

@alastairlundy
Copy link
Contributor

Added missing Span<T> Sort extension methods that are in .NET 5+ .

Tests:

#if FeatureMemory && !NET5_0_OR_GREATER

partial class PolyfillTests
{
    [Test]
    public static void DefaultSpanSortBehaviour()
    {
        var expected = Enumerable.Range(0, 10).ToArray();
        var reversed = Enumerable.Range(0, 10)
            .Reverse().ToArray();

        Span<int> actual = reversed;

        Span<char> chars = ['d', 'c', 'b', 'a'];

        chars.Sort();

        Assert.That(expected.SequenceEqual(actual));
    }

    [Test]
    public static void Sort_Comparison_HighToLow()
    {
        var expected = Enumerable.Range(0, 10).Reverse().ToArray();
        var notReversed = Enumerable.Range(0, 10).ToArray();

        Span<int> actual = notReversed;

        actual.Sort((x, y) => x.CompareTo(y));

        Assert.That(expected.SequenceEqual(actual));
    }

    [Test]
    public static void Sort_Separate_Spans_Comparison_HighToLow()
    {
        var expectedKeys = Enumerable.Range(0, 3).Reverse().ToArray();
        var expectedItems = new[]{'a', 'b', 'c'}.AsEnumerable().Reverse().ToArray();

        var actualKeys = Enumerable.Range(0, 3).ToArray();
        var actualItems = new[]{'a', 'b', 'c'};

        Span<int> actualKeysSpan = actualKeys;

        actualKeysSpan.Sort(actualItems, (x, y) => x >= y ? 1 : -1);

        Assert.That(expectedKeys.SequenceEqual(actualKeys));
        Assert.That(expectedItems.SequenceEqual(actualItems));
    }
}
#endif

Consume:
Updated Span Methods:

#if FeatureMemory

    void Span_Methods()
    {
        var span = new Span<char>(new char[1]);
        _ = span.TrimEnd();
        _ = span.TrimStart();

        var array = Enumerable.Range(0, 5).ToArray();

#if !NET8_0_OR_GREATER
        Polyfill.Shuffle(array);
#else
        Random.Shared.Shuffle(array);
#endif

        var numbers = new Span<int>(array);
        numbers.Sort();
    }

#endif

Readme:

* `void Sort<T>(Span<T>) where T : IComparable<T>` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sort?view=net-10.0#system-memoryextensions-sort-1(system-span((-0))))
* `void Sort<T, TComparer>(Span<T>, TComparer) where TComparer : IComparer<T>` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sort?view=net-10.0#system-memoryextensions-sort-2(system-span((-0))-1)) 
* `void Sort<TKey, TValue, TComparer>(Span<TKey>, Span<TValue>, TComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sort?view=net-10.0#system-memoryextensions-sort-3(system-span((-0))-system-span((-1))-2))
* `void Sort<TKey, TValue>(Span<TKey>, Span<TValue>)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sort?view=net-8.0#system-memoryextensions-sort-2(system-span((-0))-system-span((-1))))
* `void Sort<TKey, TValue>(Span<TKey>, Span<TValue>, Comparison<TKey>)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sort?view=net-10.0#system-memoryextensions-sort-2(system-span((-0))-system-span((-1))-system-comparison((-0))))

@SimonCropp
Copy link
Owner

can u update from the main line

@alastairlundy
Copy link
Contributor Author

can u update from the main line

Done.

@SimonCropp
Copy link
Owner

seems the build failed?

@alastairlundy
Copy link
Contributor Author

seems the build failed?
Didn't realize the Test framework/library changed. I've switched the methods to be async, return Tasks, and await Asserts.

Despite being on the latest changes from main, Rider says it can't resolve Test or Assert from TUnit and thinks there's missing NUnit references even though the project's switched to TUnit. I've tried rebuilding it with no change in errors.

Every test class gives these errors:
Error CS0246 : The type or namespace name 'TestAttribute' could not be found (are you missing a using directive or an assembly reference?)

Error CS0246 : The type or namespace name 'Test' could not be found (are you missing a using directive or an assembly reference?)

@alastairlundy
Copy link
Contributor Author

@SimonCropp Should be fixed now. As an aside it would be nice to be able to use Ensure inside of Polyfill itself even if consuming projects don't enable it. Using it inside of Polyfill right now causes errors.

@alastairlundy
Copy link
Contributor Author

Not sure why it's still failing on Appveyor but I'll keep looking into it.

@alastairlundy alastairlundy marked this pull request as draft December 17, 2025 17:33
@alastairlundy
Copy link
Contributor Author

@SimonCropp Well now it's failing for an entirely different reason which started after most recently merging main into this branch. Consume can't find the extension method when it can sees the other Memory extension methods in Polyfill.

Was there any Memory related configuration or packaging changes in main recently?

@SimonCropp
Copy link
Owner

@alastairlundy your changes look basically good. I am going to merge this, and trouble shoot the build on my side.

@SimonCropp SimonCropp changed the base branch from main to add-span-sort December 22, 2025 10:40
@SimonCropp SimonCropp marked this pull request as ready for review December 22, 2025 10:40
@SimonCropp SimonCropp merged commit b9a4646 into SimonCropp:add-span-sort Dec 22, 2025
1 of 2 checks passed
@alastairlundy alastairlundy deleted the add-span-sort branch December 29, 2025 17:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants