2014-09-03 44 views
2

我已經閱讀了大量正確實施Equals()GetHashCode()的文章。我有一些有很多成員變量的類,爲此我必須實現一個Equals()方法。到現在爲止還挺好。但是,當實施GetHashCode()時,我總是發現一個好的實現。據我所知,某些類別他們永遠不會用在字典或散列表中,我不想花時間編寫一個好的GetHashCode()實現,所以我想出了以下虛擬「默認」實現:如果不需要GetHashCode()虛擬實現

public override int GetHashCode() 
{ 
    Debug.Fail("If you see this message, implement GetHashCode() properly"); 

    // Always return the same value for all instances of this class. This ensures 
    // that two instances which are equal (in terms of their Equals() method) 
    // have the same hash code. 
    return 0; 
} 

我想問你的意見,如果這是一個可行的方法。

一方面,我不想花時間在執行GetHashCode()時,我不必。另一方面,我希望我的代碼乾淨有效。上述實現確保具有相同Equals()結果的兩個實例也具有相同的哈希碼。當然,如果它真的會被用作字典中的關鍵字,那麼性能會很糟糕。但是對於這種情況你會得到調試斷言。

上述方法有什麼缺點,我可能錯過了?

+0

看看這個SO問題。我不會說這是重複的,但它是絕對相關的:http://stackoverflow.com/questions/263400/what-is-the-best-algorithm-for-an-overridden-system-object-gethashcode – Konamiman 2014-09-03 14:39:28

+1

個人意見:調試和發佈版本之間的顯着差異(如崩潰與樣本成功)是不好的主意。 – 2014-09-03 14:39:31

+0

@AlexeiLevenkov這段代碼在調試和發佈之間無顯着差異。如果'Debug.Fail'被執行並且被忽略,則沒有區別。另請參閱我對Jon Skeet的答案的評論。 – Tobias 2014-09-03 15:41:40

回答

4

如果你真的不想實現它,我會建議拋出異常(例如NotImplementedException) - 那麼你不只是依靠Debug.Fail工作。如果您在生產環境中遇到這種情況,那麼快速失敗可能是最好的選擇。

不過說實話,一旦你已經實現了平等是通常很容易寫GetHashCodewith code like this, perhaps) - 如果它容易那麼這往往是你的Equals方法反正違反了合同的標誌。

注意GetHashCode只是用於字典 - 如果你嘗試加入的LINQ兩個列表根據你的類型的密鑰,即使用GetHashCode了。基本上,不執行它違反了最小驚訝的原則。除非你是只有使用你的代碼的人(你有一個完美的記憶或願意檢查每次你使用的類型),你應該正確實施,IMO。

+0

以上實現不依賴於'Debug.Fail'。這對開發人員來說只是暗示有一些東西需要優化。 'GetHashCode()'的實現/結果是0.雖然如果真的用作關鍵字,它的性能並不好,但它總是可以工作的。我知道在LINQ查詢中可能會調用'GetHashCode()',但目前情況並非如此。如果將來會有,開發人員會得到斷言,如果他忽略它,代碼仍然會工作。 – Tobias 2014-09-03 15:39:52

+0

順便說一句,拋出一個異常會違反你不應該在'GetHashCode()'中拋出異常的規則。我以前曾經這樣做過,但上述方法並不需要它。 – Tobias 2014-09-03 15:43:16

+0

@Tobias:如果您使用Join,Distinct,GroupBy等,則會調用GetHashCode *。如果違反了該方法(「此方法不會被調用」),那麼我寧願立即發現它,它由於沒有注意而在測試中工作,然後癱瘓生產用途。 – 2014-09-03 15:55:53