Closed
Description
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.