简体   繁体   中英

IEqualityComparer for nullable struct

I want to write an equality comparer for Nullable structs. Lets say, DateTime? . So I come up with this code:

public class NullableEntityComparer<TEntity, TType> : IEqualityComparer<TEntity> 
        where TType : struct
        where TEntity : Nullable<TType>
{
    public bool Equals(TEntity x, TEntity y)
    {
        if(!x.HasValue && ! y.HasValue) return true;
        if(x.HasValue && y.HasValue) return x.Value == y.Value;
        return false;
    }

    public int GetHashCode(TEntity obj)
    {
        if (obj == null) throw new ArgumentNullException("obj");
        if (obj.HasValue) return obj.Value.GetHashCode();
        else return obj.GetHashCode();
    }
}

The compiler doesn't like this and tells me:

'TType?' is not a valid constraint. A type used as a constraint must be an interface, a non-sealed class or a type parameter.   

This is a clear message, however Nullable<T> is a class, and TType? is just a shorthand for Nullable<TType> . Or am I missing something?

Why does this not work? And is there a solution to have an IEqualityComparer<T> use the T.HasValue property?

It's quite simple - Nullable<> is a struct , so it counts as a sealed class, which is prohibited in a constraint (obviously - if you use a sealed class as a constraint, there's no need to use a generic type argument - you already always have exactly the same type).

But you don't need to do this at all. Simply have TType constrained by struct , but instead of using TEntity , just use TType? whenever you need the nullable:

public class NullableEntityComparer<TType> : IEqualityComparer<TType?> 
        where TType : struct
{
    public bool Equals(TType? x, TType? y)
    {
        if(!x.HasValue && ! y.HasValue) return true;
        if(x.HasValue && y.HasValue) return x.Value.Equals(y.Value);
        return false;
    }

    public int GetHashCode(TType? obj)
    {
        return obj.GetHashCode();
    }
}

As a side-note, nullables already have an implementation of equality that includes checking for nulls, so if you can avoid all this if you know the nullable type at compile-time.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM