我想为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();
}
}
附带说明一下,可为空的对象已经具有实现相等性的实现,其中包括检查空值,因此,如果您在编译时知道可为空的类型,则可以避免所有这些情况。