用于可空结构的IEqualityComparer

时间:2015-07-29 10:10:40

标签: c# generics nullable iequalitycomparer

我想为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属性的解决方案?

1 个答案:

答案 0 :(得分:5)

这非常简单 - 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();
    }
}

作为旁注,nullables已经有一个包含检查空值的相等实现,所以如果你在编译时知道可空类型就可以避免所有这些。