[英]Overriding Object.Equals() instance method in C#; now Code Analysis/FxCop warning CA2218: “should also redefine GetHashCode”. Should I suppress this?
我在C#項目中有一個復雜的類,我希望能夠進行相等測試。 這不是一個微不足道的階級; 它包含各種標量屬性以及對其他對象和集合的引用(例如IDictionary)。 為了它的價值,我的班級是密封的。
為了在我的系統中的其他地方啟用性能優化(避免昂貴的網絡往返的優化),我需要能夠將這些對象的實例相互比較以實現相等 - 除了內置的引用相等 - 所以我重寫了Object.Equals()實例方法。 但是,現在我已經這樣做了,Visual Studio 2008的代碼分析又稱FxCop,我默認啟用它,它引發了以下警告:
警告:CA2218:Microsoft.Usage:由於'MySuperDuperClass'重新定義了Equals,它還應該重新定義GetHashCode。
我想我理解這個警告的基本原理: 如果我要將這些對象用作集合中的鍵 ,那么哈希碼很重要。 即看到這個問題 。 但是,我不打算將這些對象用作集合中的鍵。 永遠。
感覺有理由壓制警告,我在MSDN文檔中查找了代碼CA2218以獲取警告的全名,因此我可以將SuppressMessage
屬性應用於我的類,如下所示:
[SuppressMessage("Microsoft.Naming",
"CA2218:OverrideGetHashCodeOnOverridingEquals",
Justification="This class is not to be used as key in a hashtable.")]
但是,在進一步閱讀時,我注意到以下內容:
如何修復違規行為
要修復違反此規則的行為,請提供GetHashCode的實現。 對於一對相同類型的對象,如果Equals的實現為該對返回true,則必須確保實現返回相同的值。
何時抑制警告
-----> 不要壓制此規則的警告。 [箭頭和重點我的]
所以,我想知道: 為什么我不應該按照我的計划來壓制這個警告? 我的情況不是要求抑制嗎? 我不想為這個永遠不會被調用的對象編寫GetHashCode()的實現,因為我的對象永遠不會成為集合中的鍵。 如果我想要迂腐而不是抑制,那么用一個拋出NotImplementedException的實現覆蓋GetHashCode()會更合理嗎?
如果您定義的類型不會被用作容器中的鍵,那么這無關緊要。 表示窗口控件,網頁控件或數據庫連接的類型不太可能用作集合中的鍵。 在那些情況下,什么都不做。 即使效率非常低,所有引用類型都將具有正確的哈希碼。 [...]在您創建的大多數類型中,最好的方法是完全避免GetHashCode()的存在。
...這就是我最初得到這個想法,我不必總是關注GetHashCode()。
如果你是reallio-trulio absosmurfly 肯定你永遠不會使用這個東西作為哈希表的關鍵,那么你的提議是合理的。 覆蓋GetHashCode; 讓它拋出一個例外。
請注意,哈希表隱藏在不太可能的地方。 大量LINQ序列運算符在內部使用哈希表實現來加快速度。 通過拒絕GetHashCode的實現,您也拒絕在各種LINQ查詢中使用您的類型。 我喜歡構建使用memoization來提高速度的算法; memoizers通常使用哈希表。 因此,您也拒絕記住將類型作為參數的方法調用的能力。
或者,如果你不想那么苛刻: 覆蓋GetHashCode; 使它總是返回零。 這符合GetHashCode的語義要求; 兩個相等的對象總是具有相同的哈希碼。 如果它曾經被用作字典中的關鍵字,那么性能會很糟糕,但是當它出現時你可以處理它,你聲稱它永遠不會。
所有這一切:來吧。 您可能花了更多時間來輸入問題,而不是正確實現它。 去做就對了。
你不應該壓制它。 看看你的equals方法是如何實現的。 我確信它比較了班上的一個或多個成員來確定平等。 其中一個成員通常足以區分一個對象,因此您可以通過返回membername.GetHashCode();
來實現GetHashCode
membername.GetHashCode();
。
我的價值0.10美元? 實現GetHashCode。
就像你說你永遠不會需要它一樣,你可能會改變主意,或者其他人可能對如何使用代碼有其他想法。 工作GetHashCode並不難,並保證將來不會出現任何問題。
一旦你忘記了,或者另一個不知道的開發人員使用了這個,有人會有一個痛苦的錯誤來追查。 我建議只是正確實現GetHashCode,然后你就不用擔心了。 或者只是不要將Equals用於特殊的相等比較案例。
GetHashCode
和Equals
方法協同工作,為您的類型提供基於值的相等語義 - 您應該一起實現它們。
有關此主題的更多信息,請參閱以下文章:
無恥的插件:這些文章是我寫的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.