我被一個看似簡單的問題困住了。我有兩個對象,我正在比較!=。哈希碼相同,但!=返回true?
當我運行該應用程序時,a!= b爲真。 當我放置斷點並執行Watch時,a.GetHashCode()== b.GetHashCode()爲true。
這兩個(引用類型)對象在不同的程序集中定義,但我找不到對!=方法的重寫(儘管GetHashCode被重寫)。對此有另一種解釋嗎?有可能兩個對象的GetHashCode可能是相同的,但是一個not-overriden!=會返回true?
謝謝。
我被一個看似簡單的問題困住了。我有兩個對象,我正在比較!=。哈希碼相同,但!=返回true?
當我運行該應用程序時,a!= b爲真。 當我放置斷點並執行Watch時,a.GetHashCode()== b.GetHashCode()爲true。
這兩個(引用類型)對象在不同的程序集中定義,但我找不到對!=方法的重寫(儘管GetHashCode被重寫)。對此有另一種解釋嗎?有可能兩個對象的GetHashCode可能是相同的,但是一個not-overriden!=會返回true?
謝謝。
當兩個不同的對象返回相同的代碼時,它被稱爲「碰撞」。只有大約40億個可能的整數值,以及超過40億個[你的班級名稱]的可能值,一些衝突是不可避免的。這就是爲什麼基於散列的結構(即Dictionary
)不能完全依賴於GetHashCode
,它還需要一個合理的實現纔能有效。 Equals
方法是用於解決這些衝突的方法。
當然,類的創建者也可能覆蓋GetHashCode
或Equals
,並且在某種程度上犯了一個錯誤,以某種方式違反了生成哈希碼的「合同」。 Here是創建GetHashCode
方法時要牢記的一條準則列表。請記住,有一小部分事情要做,而另一組事情可以通過高效地工作來實現。。
return 0;
實際上是一個完全可以接受的GetHashCode
實現。它符合所有的規則,它只有100%的機率造成衝突,所以它將是非常低效的,你永遠不應該這樣做。
對於不等於具有相同散列碼的兩個對象是完全合法的,但對於具有不同散列碼的兩個對象是無效的。
字典樣式集合類使用哈希碼值(從指定爲對象的對象返回的GetHashCode值)將鍵/值對放入哈希表中。密鑰的哈希代碼值相同的所有鍵/值對都會進入同一個哈希表。如果哈希碼生成是有效的,那麼意味着字典中的每個非空哈希表中將會有非常少的(希望只有一個)鍵/值對。
當通過指定一個對象作爲鍵來訪問在字典中的內容,爲找到正確的值將被返回的僞邏輯是:
與查找List樣式集合中的對象(哈希碼分佈良好時)相比,這使得字典查找非常有效。
如果在調試散列算法時碰巧遇到碰撞,那麼最有可能極其糟糕。 – Magnus
@Magnus完全取決於情況。他們是否創建了兩個發生碰撞的對象(可能性是40億分之一),還是創建了很多對象,並假定哈希代碼是唯一的,並且其代碼因此而中斷?在第二種情況下,賠率是'numberOfGeneratedObjects /〜40億' – Servy
確定你是對的。順便說一下,40億分之一的人認爲使用了一種完美的哈希算法,但事實上,其可能性要低得多。 (除非數據類型是隻返回自身的int32。) – Magnus