Skip to content

[API Proposal]: Employ allows ref struct in comparer interfaces #103323

Closed
@hamarb123

Description

@hamarb123

EDITED on 6/17/2024 by @stephentoub to add more interfaces

Background and motivation

Similar to #102671.
Similar to #103270.
I discovered this gap as I attempted to pre-emptively implement .NET 9 allows ref struct on some of my own APIs behind a #if to see which APIs missing it would cause me problems.
We have done the same thing for IEnumerable<T> and IEnumerator<T> already.

API Proposal

namespace System.Collections.Generic;

public interface IComparable<T>
+   where T : allows ref struct
{
    ...
}

public interface IComparer<in T>
+   where T : allows ref struct
{
    ...
}

public interface IEquatable<T>
+   where T : allows ref struct
{
    ...
}

public interface IEqualityComparer<in T>
+    where T : allows ref struct
{
    ...
}

public interface IAlternateEqualityComparer<in TAlternate, T>
    where TAlternate : allows ref struct
+   where T : allows ref struct
{
    ...
}

API Usage

struct SpanSequenceComparer<T> : IEqualityComparer<ReadOnlySpan<T>>, IEqualityComparer<Span<T>>
{
    public readonly bool Equals(ReadOnlySpan<T> x, ReadOnlySpan<T> y)
    {
        if (x.Length != y.Length) return false;
        for (int i = 0; i < x.Length; i++)
        {
            if (!EqualityComparer<T>.Default.Equals(x[i], y[i])) return false;
        }
        return true;
    }

    public readonly bool Equals(Span<T> x, Span<T> y) => Equals((ReadOnlySpan<T>)x, (ReadOnlySpan<T>)y);

    public readonly int GetHashCode(ReadOnlySpan<T> obj)
    {
        HashCode hc = new();
        hc.Add(obj.Length);
        for (int i = 0; i < obj.Length; i++) hc.Add(EqualityComparer<T>.Default.GetHashCode(obj[i]));
        return hc.ToHashCode();
    }

    public readonly int GetHashCode(Span<T> obj) => GetHashCode((ReadOnlySpan<T>)obj);
}

Alternative Designs

Also implement on readonly collection types:

public interface IReadOnlyCollection<out T>
+    where T : allows ref struct
{
    ...
}

public interface IReadOnlyList<out T>
+    where T : allows ref struct
{
    ...
}

public interface IReadOnlySet<T>
+    where T : allows ref struct
{
    ...
}

Risks

These are interfaces, so none really.

Metadata

Metadata

Assignees

Labels

api-ready-for-reviewAPI is ready for review, it is NOT ready for implementationarea-System.CollectionsblockingMarks issues that we want to fast track in order to unblock other important workin-prThere is an active PR which will close this issue when it is merged

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions