[英]C# Is this a bad way to implement GetHashCode?
我正在嘗試為覆蓋Equals的對象實現GetHashCode。
public override bool Equals(object obj)
{
var myobject = obj as MyObject;
if (myobject == null)
return false;
if (myobject.SomeProperty == null || SomeProperty == null)
return false;
// All default SomeProperty's are equal
if (myobject.SomeProperty.IsDefault)
return SomeProperty.IsDefault;
// Otherwise equality is based on ID
return myobject.SomeProperty.ID == SomeProperty.ID;
}
public override int GetHashCode()
{
if (SomeProperty != null && SomeProperty.IsDefault)
return 0;
else return base.GetHashCode();
}
這是一種合理的方法,還是可能導致與base.GetHashCode()的沖突?
編輯:我感謝到目前為止給出的解決方案,但仍然存在相同的問題。 如果我沒有實現完整的GetHashCode並依賴於base.GetHashCode()或Guid.GetHashCode()的其他實現,那么哈希代碼是否有可能與硬編碼0值沖突? 如果是這樣,有沒有一種簡單的方法可以避免這種情況?
根據您的Equals
方法,您認為真正是對象的“身份”的是SomeProperty.ID
的值,還需要對null值/ properties / etc進行一些其他處理。
這也應該反映在哈希碼中。
您應該像處理Equals
方法一樣開始處理所有這些極端情況。 好像您有點兒走這條路,但還沒到那兒。 如果對象的SomeProperty
為null 或 IsDefault
則它沒有ID,對我們來說,所有此類對象都是“相同的”,並且應具有相同的哈希碼。
不過,在那之后,您無需真正利用基類的哈希碼,而需要將哈希實際基於ID
屬性,這是您的Equals
方法接下來要做的。 由於ID
是Guid
我們知道它具有明智的GetHashCode
實現,因此我們可以利用它,然后完成了:
public override int GetHashCode()
{
if (SomeProperty == null || SomeProperty.IsDefault)
return 0;
else
return SomeProperty.ID.GetHashCode();
}
或者,如果您更容易閱讀,我們可以顛倒邏輯。 與其說“如果沒有ID,則返回零,否則返回ID的哈希碼”,我們可以說:“如果有ID,則返回其哈希碼,否則僅返回零:
public override int GetHashCode()
{
if (SomeProperty != null && !SomeProperty.IsDefault)
return SomeProperty.ID.GetHashCode();
else
return 0;
}
我個人認為第一個與您的Equals
方法具有更多的對稱性,但是第二個似乎與您嘗試執行的操作更加接近,這就是為什么我將它扔在那里的原因。
那不是一個好的解決方案。 文檔顯示
哈希函數必須具有以下屬性:
如果兩個對象比較相等,則每個對象的GetHashCode方法必須返回相同的值。 但是,如果兩個對象的比較不相等,則兩個對象的GetHashCode方法不必返回不同的值。
只要沒有修改確定對象的Equals方法返回值的對象狀態,對象的GetHashCode方法就必須始終返回相同的哈希碼。 請注意,這僅適用於當前執行的應用程序,並且如果再次運行該應用程序,則可以返回不同的哈希碼。
為了獲得最佳性能,哈希函數必須為所有輸入生成隨機分布。
您可能會為許多不相等的對象返回0,盡管這不會破壞租戶“如果兩個對象的比較不相等,則兩個對象的GetHashCode方法不必返回不同的值”,如果太多的對象返回0,則您不會滿足“為獲得最佳性能,散列函數必須為所有輸入生成隨機分布。”
此外,
重寫GetHashCode的派生類也必須重寫Equals,以確保被認為相等的兩個對象具有相同的哈希碼。 否則,哈希表類型可能無法正常工作。
因此,還應發布您正在執行的Equals,以確保GetHashCode有效。
我建議將其更新為
public override int GetHashCode()
{
if (SomeProperty == null || SomeProperty.IsDefault)
return base.GetHashCode() ;
else return SomeProperty.ID.GetHashCode();
}
另外,為了更好地討論GetHashCode實現,您可以查看這篇文章
另外,在相等中,如果兩個對象中的SomeProperty==null
都返回false
,那是故意的嗎?
還是你的意思
if (myobject.SomeProperty == null && SomeProperty == null)
return true;
if (myobject.SomeProperty == null || SomeProperty == null)
return false;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.