Skip to content

[API Proposal]: Remove IEquatable<T>? constraint on ArgumentOutOfRangeException ThrowIfEqual/ThrowIfNotEqual #118053

@bill-poole

Description

@bill-poole

Background and motivation

The ThrowIfEqual and ThrowIfNotEqual methods on the ArgumentOutOfRangeException class both have a where T : IEquatable<T>? constraint. However, the implementations of these methods do not seem to rely on this constraint, using EqualityComparer<T>.Default.Equals(T?, T?), which does not require T to implement IEquatable<T>.

The IEquatable<T> constraint prevents us from using the ThrowIfEqual and ThrowIfNotEqual methods on nullable value types (e.g., int?).

However, we can circumvent this constraint by wrapping the parameters in a ValueTuple<T> struct because ValueTuple<T> implements IEquatable<ValueTuple<T>>, but does not require T : IEquatable<T>. For example:

int? x = 10;
ArgumentOutOfRangeException.ThrowIfNotEqual(new ValueTuple<int?>(x), new ValueTuple<int?>(20));

Therefore it seems that the IEquatable<T> constraint should be removed from the ThrowIfEqual and ThrowIfNotEqual methods given that the ThrowIfEqual method is basically performing the same function as ValueTuple<T>.Equals(ValueTuple<T>), which does not have this constraint.

API Proposal

namespace System;

public class ArgumentOutOfRangeException : ArgumentException
{
    public static void ThrowIfEqual<T>(T value, T other, 
        [CallerArgumentExpression(nameof(value))] string? paramName = null);

    public static void ThrowIfNotEqual<T>(T value, T other, 
        [CallerArgumentExpression(nameof(value))] string? paramName = null);
}

API Usage

int? x = 10;
ArgumentOutOfRangeException.ThrowIfNotEqual(x, 20);

Alternative Designs

No response

Risks

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions