Skip to content

API Proposal: MemoryExtensions.SequenceEqual with IComparer<T> #48304

Description

@stephentoub

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);
}

Metadata

Metadata

Assignees

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions