当对象的标识符为空时,GetHashCode应该返回什么?

考虑到identity属性可以为null,以下哪项是正确/更好的。

public override int GetHashCode() { if (ID == null) { return base.GetHashCode(); } return ID.GetHashCode(); } 

要么

 public override int GetHashCode() { if (ID != null) { return ID.GetHashCode(); } return 0; } 

更新1:更新了第二个选项。

更新2:以下是Equals实现:

 public bool Equals(IContract other) { if (other == null) return false; if (this.ID.Equals(other.ID)) { return true; } return false; } public override bool Equals(object obj) { if (obj == null) return base.Equals(obj); if (!obj is IContract) { throw new InvalidCastException("The 'obj' argument is not an IContract object."); } else { return Equals((IContract)obj); } } 

ID是string类型。

这实际上取决于你想要什么样的平等 – 重要的是两个相等的对象返回相同的哈希码。 当ID为空时,等式意味着什么? 目前,如果ID属性具有相同的值,则您的Equals方法必须返回true …但是如果ID为null,我们不知道它的作用。

如果你真的想要第一个版本的行为,我个人会使用:

 return ID == null ? base.GetHashCode() : ID.GetHashCode(); 

编辑:根据你的Equals方法,看起来你可以制作你的GetHashCode方法:

 return ID == null ? 0 : ID.GetHashCode(); 

请注意,您的Equals(IContract other)方法也可能如下所示:

 return other != null && object.Equals(this.ID, other.ID); 

如果this.ID为null,您当前的实现将实际抛出exception…

另外,你的Equals(object)方法是不正确的 – 如果你传递了一个不合适的对象类型,你不应该抛出exception,你应该只返回false … ditto如果obj为null。 所以你实际上可以使用:

 public override bool Equals(object obj) { return Equals(obj as IContract); } 

但是,我担心基于接口的相等性。 通常,即使实现相同的接口,也不应认为两类不同类型是相等的。

你可以简单地return 0; ,你需要为相同的值返回相同的HashCode,而ID.GetHashCode()通常不会返回0,所以这样的Hash函数可以满足任何需求。 由于你没有组合任何值(比如ID和Name Hashes),它非常清晰的ID是HashCode的定义源,因此Null ID的固定0听起来合理。

否则,您在GetHashCode上的整个方法覆盖只考虑ID字段是错误的(并且您需要组合多个字段来计算它们的哈希值)

在您编辑之后,我可以说第二个Equals覆盖有太多代码,只需将其替换为

 public override bool Equals(object obj) { return Equals(obj as Contract); } 

你的Equals(IContract合同)覆盖对我来说是错误的,因为只有定义合同的东西是ID,如果IContract有更多的字段而不是ID,那么它将是一个糟糕的Equals覆盖。

PS:实际上如果IContract是一个接口,你可能需要将IEquatable替换为具体的IEquatable合同,因为它将是一个糟糕的设计,能够返回实现相同接口的不同类实例相同导致相等根据定义,需要在相等性检查的第一阶段检查对象是否具有相同的类型(通常在99.9%的情况下)

也许你想要的是这样的?

 override int GetHashCode() { if (ID != null) return ID.GetHashCode(); return DBNull.Value.GetHashCode(); } 

重要的是,如果两个具有空ID的对象被认为是相等的吗?