我想为Nullable结构编写一个相等比较器。可以说DateTime?
所以我想出了这段代码:

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


编译器不喜欢这样,并告诉我:

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


这是一条清晰的消息,但是Nullable<T>是一个类,而TType?只是Nullable<TType>的简写。还是我错过了什么?

为什么这不起作用?是否有一种解决方法可以让IEqualityComparer<T>使用T.HasValue属性?

最佳答案

这很简单-Nullable<>struct,因此它被视为密封类,在约束中禁止使用(显然-如果将密封类用作约束,则无需使用泛型类型参数-您已经具有完全相同的类型)。

但是您根本不需要这样做。只需将TType约束为struct,但无需使用TEntity,只要需要空值即可使用TType?

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


附带说明一下,可为空的对象已经具有实现相等性的实现,其中包括检查空值,因此,如果您在编译时知道可为空的类型,则可以避免所有这些情况。

10-08 02:18