[英]What to return when overriding Object.GetHashCode() in classes with no immutable fields?
[英]What should GetHashCode return when object's identifier is null?
考慮到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,您當前的實現將實際拋出異常...
另外,你的Equals(object)
方法是不正確的 - 如果你傳遞了一個不合適的對象類型,你不應該拋出異常,你應該只返回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<IContract>
替換為具體的IEquatable<ClassName>
合同,因為它將是一個糟糕的設計,能夠返回實現相同接口的不同類實例是相同的因果相等根據定義,需要在相等性檢查的第一階段檢查對象是否具有相同的類型(通常在99.9%的情況下)
也許你想要的是這樣的?
override int GetHashCode()
{
if (ID != null)
return ID.GetHashCode();
return DBNull.Value.GetHashCode();
}
重要的是,如果兩個具有空ID的對象被認為是相等的嗎?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.