Background and Motivation
We currently have MemoryExtensions.SequenceEqual overloads that work with spans, but they constrain T : IEquatable<T>:
public static bool SequenceEqual<T>(this System.ReadOnlySpan<T> span, System.ReadOnlySpan<T> other) where T : System.IEquatable<T> { throw null; }
public static bool SequenceEqual<T>(this System.Span<T> span, System.ReadOnlySpan<T> other) where T : System.IEquatable<T> { throw null; }
This means there's no built-in support for using IEqualityComparer<T>. It also means APIs like Enumerable.SequenceEqual that are unconstrained aren't able to delegate to this in general when provided with array inputs.
Proposed API
public static class MemoryExtensions
{
public static bool SequenceEqual<T>(this System.ReadOnlySpan<T> span, System.ReadOnlySpan<T> other, IEqualityComparer<T>? comparer);
public static bool SequenceEqual<T>(this System.Span<T> span, System.ReadOnlySpan<T> other, IEqualityComparer<T>? comparer);
...
}
We could also consider doing the same thing for SequenceCompareTo, taking the existing overloads and adding new ones that remove the constraint and accept a nullable IComparer<T>.
The implementations would delegate to the existing implementations if comparer is null and T is found to be IEquatable<T> (maybe just for value types). Otherwise, they'd loop through the spans comparing each element.
Usage Examples
For example, we would change Enumerable.SequenceEqual to do:
if (first is TSource[] firstArray && second is TSource[] secondArray)
{
return ((ReadOnlySequence<TSource>)firstArray).SequenceEqual(secondArray, comparer);
}
Background and Motivation
We currently have MemoryExtensions.SequenceEqual overloads that work with spans, but they constrain
T : IEquatable<T>:This means there's no built-in support for using
IEqualityComparer<T>. It also means APIs likeEnumerable.SequenceEqualthat are unconstrained aren't able to delegate to this in general when provided with array inputs.Proposed API
We could also consider doing the same thing for SequenceCompareTo, taking the existing overloads and adding new ones that remove the constraint and accept a nullable
IComparer<T>.The implementations would delegate to the existing implementations if comparer is null and T is found to be
IEquatable<T>(maybe just for value types). Otherwise, they'd loop through the spans comparing each element.Usage Examples
For example, we would change
Enumerable.SequenceEqualto do: