可空结构的 IEqualityComparer
IEqualityComparer for nullable struct
我想为 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>
是 class,TType?
只是 Nullable<TType>
的 shorthand。还是我遗漏了什么?
为什么这不起作用?有没有办法让 IEqualityComparer<T>
使用 T.HasValue
属性?
这很简单 - Nullable<>
是一个 struct
,所以它算作一个密封的 class,这在约束中是被禁止的(显然 - 如果你使用密封的 class 作为约束,无需使用泛型类型参数 - 您已经始终拥有完全相同的类型)。
但你根本不需要这样做。只需将 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();
}
}
附带说明一下,可空对象已经实现了相等性,其中包括检查空值,因此,如果您在编译时知道可空类型,就可以避免这一切。
我想为 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>
是 class,TType?
只是 Nullable<TType>
的 shorthand。还是我遗漏了什么?
为什么这不起作用?有没有办法让 IEqualityComparer<T>
使用 T.HasValue
属性?
这很简单 - Nullable<>
是一个 struct
,所以它算作一个密封的 class,这在约束中是被禁止的(显然 - 如果你使用密封的 class 作为约束,无需使用泛型类型参数 - 您已经始终拥有完全相同的类型)。
但你根本不需要这样做。只需将 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();
}
}
附带说明一下,可空对象已经实现了相等性,其中包括检查空值,因此,如果您在编译时知道可空类型,就可以避免这一切。