2015-03-03 58 views
1

以下代碼是否正常?基於GetHashCode的Equals是否有負面影響?

public override bool Equals(object obj) 
{ 
    if (obj == null || !(obj is LicenseType)) 
    return false; 
    return GetHashCode() == obj.GetHashCode(); 
} 

public override int GetHashCode() 
{ 
    return 
    Vendor.GetHashCode()^
    Version.GetHashCode()^
    Modifiers.GetHashCode()^
    Locale.GetHashCode(); 
} 

所有屬性是枚舉/數字字段,並且是定義LicenseType對象的唯一特性。

+0

即使取決於哈希碼是好的,您的GetHashCode的實現並不好,你應該看看http://stackoverflow.com/a/720282/267 – 2015-03-03 11:01:40

+0

這不是一個特別合理的哈希代碼實現:http ://ericlippert.com/2011/02/28/guidelines-and-rules-for-gethashcode/ – 2015-03-03 11:04:07

+0

的GetHashCode用作幹什麼的正式成員,由成員平等比較之前快速檢查。一個好的hashcode實現很重要,因爲像Dictionary這樣的集合使用它來創建桶。字典將使用密鑰的哈希碼來定位合適的桶,然後使用相等來查找完全匹配。 – 2015-03-03 11:26:16

回答

6

沒有,the documentation狀態很清楚:

你不應該假定等於哈希碼暗示對象相等。

另外:

兩個對象是相等的回報相同的散列碼。但是,反過來是不正確的:相等的散列碼並不意味着對象平等

和:

注意:

  • 不要測試的散列碼平等確定兩個對象是否相等。 (不相等的對象可以具有相同的散列碼。)要測試相等性,請調用ReferenceEqualsEquals方法。
6

當兩個不同的對象返回相同的HashCodes時會發生什麼?

畢竟,它只是一個散列,因此在對象可以具有的所有值範圍內都可能不是獨特的。

1

只要GetHashCode對於每個可能的值都是唯一的,這沒關係(沒有負面影響)。舉個例子,short(16位值)的GetHashCode總是唯一的(讓我們希望如此:-)),所以將Equals設置爲GetHashCode即可。

另一個例子,對於intGetHashCode()是整數的值,所以我們有那個((int)value).GetHashCode() == ((int)value)。請注意,例如short(但仍然是short的散列碼是唯一的,它們只使用更復雜的公式),但這不是真實的。

請注意,Patrick寫的是錯誤的,因爲對於對象/類的「用戶」。你是對象/類的「作者」,所以你定義了相等的概念和散列碼的概念。如果你定義兩個對象總是相等的,無論它們的值是多少,那麼就沒關係。

public override int GetHashCode() { return 1; } 
public override bool Equals(object obj) { return true; } 

爲等於唯一重要rules是:

需要

實施,以確保如果Equals方法爲兩個對象x和y返回true,則通過X GetHashCode方法返回的值必須等於爲y返回的值。

equals方法是自反的,對稱的,傳遞的...

顯然你Equals()GetHashCode()都OK這個規則,所以他們是好的。

只是出於好奇,存在至少對於等號(==)異常(通常定義基於所述Equals方法等於運算符)

bool v1 = double.NaN.Equals(double.NaN); // true 
bool v2 = double.NaN == double.NaN; // false 

這是因爲NaN值在所定義IEEE 754標準與所有值不同,包括NaN。出於實際原因,Equals返回true

0

必須注意,這不是一個規則,如果兩個對象具有相同的散列碼,那麼他們必須相等。

只有四個十億左右可能的散列碼,但顯然也有超過四個十億可能的對象。僅有40多億十個字符的字符串。因此,Pigeonhole原則必須至少有兩個不相同的對象共享相同的散列碼。

假設你有一個有一堆像姓名,地址字段,等等Customer對象。如果在兩個不同的進程中使兩個這樣的對象具有完全相同的數據,則它們不必返回相同的哈希碼。如果星期二在一個進程中創建了這樣一個對象,關閉它,並在週三再次運行該程序,哈希代碼可能會不同。

這咬傷人過去。 System.String.GetHashCode的文檔具體指出,兩個相同的字符串在CLR的不同版本中可以具有不同的哈希碼,事實上它們的確可以。不要在數據庫中存儲字符串哈希值,並期望它們永遠是相同的,因爲它們不會。

相關問題