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

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions