Generic extension method for NullIf() supporting nullable and non-nullable value types I would like a simple, modestly efficient NullIf() generic extension for nullable and non-nullable value types including enums. The trickiness seems to be with equality testing in generics.

Any issues with this working implementation?

/// &lt;summary&gt;
/// Return null if the value is equal to the argument.  Applies to value types including enums.
/// &lt;/summary&gt;
public static T? NullIf&lt;T&gt;(this T value, T equalsThis) 
    where T : struct, IComparable // values types (including enum)
{
    return Comparer&lt;T&gt;.Default.Compare(value, equalsThis) == 0
        ? (T?)null
        : value;
}

/// &lt;summary&gt;
/// Return null if the value is null or the value is equal to the argument.
/// Applies to value types including enums.
/// &lt;/summary&gt;
public static T? NullIf&lt;T&gt;(this T? value, T equalsThis) 
    where T : struct, IComparable  // values types (including enum)
{
    return !value.HasValue
        ? (T?)null
        : value.Value.NullIf(equalsThis);
}


Test cases:

int i = 32;
int? i2 = i.NullIf(32); // null
int? i3 = i.NullIf(50); // 32

System.IO.FileAccess fa = System.IO.FileAccess.Read;
System.IO.FileAccess? fa2 = fa.NullIf(System.IO.FileAccess.Read);       // null
System.IO.FileAccess? fa3 = fa.NullIf(System.IO.FileAccess.ReadWrite);  // Read


References: Comparer&lt;T&gt;.Default
Just a couple of observations:

Neither Comparer&lt;T&gt; nor IComparer&lt;T&gt; pose any type restrictions on T. So I don't see any need for imposing an IComparable restriction in the implementation.
The other option would be to keep the IComparable restriction and make actually use of that interface (i.e. return value.CompareTo(equalsThis) == 0)

IComparable is the wrong abstraction to use. IComparable is meant for objects to provide a sort order as it has the concept of smaller, equal and greater. For your purposes you simply want to test for equality - so you should use IEquatable&lt;T&gt; or EqualityComparer&lt;T&gt; instead.


Update:
Turns out that enums generally don't implement IEquatable&lt;T&gt;. The best option in that case would probably be to allow the user to optionally pass in an IEqualityComparer&lt;T&gt; defaulting to EqualityComparer&lt;T&gt;.Default and again not impose any additional type restrictions.