日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

NET问答: 重写了 Equals,还有必要重写 GetHashCode 吗?

發布時間:2023/12/4 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 NET问答: 重写了 Equals,还有必要重写 GetHashCode 吗? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

咨詢區

  • David Basarab

直入主題,參考如下代碼:

public?class?Foo {public?int?FooId?{?get;?set;?}public?string?FooName?{?get;?set;?}public?override?bool?Equals(object?obj){Foo?fooItem?=?obj?as?Foo;if?(fooItem?==?null)?{return?false;}return?fooItem.FooId?==?this.FooId;}public?override?int?GetHashCode(){//?Which?is?preferred?return?base.GetHashCode();//return?this.FooId.GetHashCode();} }

這里的 Foo 表示 table 中的 row,請問在重寫 GetHashCode() 方法時我該用哪一種實現呢?

  • base.GetHashCode();

  • this.FooId.GetHashCode();

回答區

  • Marc Gravell

如果你的 item 要作為 Dictionary 和 HashSet 中的key時,那重寫 GetHashCode() 簡直就是剛需,因為集合會根據 item 的 hashcode 對 item 進行分組,如果兩個 item 的 hashcode 不一樣,那么 equals 將永遠不會被調用,GetHashCode() 方法應該要體現 Equals 的邏輯,比較方式大概如下:

  • 如果 Equals 判定為相等,那么 GetHashCode 必須相等。

  • 如果 GetHashCode 判定為相等,那么 Equals 不一定相等。

再回到你的場景,用 return FooId 來作為 GetHashCode() 的實現是合理的。

不過作為一般場景,當 item 中有多個屬性,推薦的做法是組合多個屬性,代碼如下:

unchecked?//?only?needed?if?you're?compiling?with?arithmetic?checks?enabled {?//?(the?default?compiler?behaviour?is?*disabled*,?so?most?folks?won't?need?this)int?hash?=?13;hash?=?(hash?*?7)?+?field1.GetHashCode();hash?=?(hash?*?7)?+?field2.GetHashCode();...return?hash; }

值得一提是,上面的 hashcode 實現也解決了一個經典的 對角線沖突 問題,比如說:new Foo(3,5) != new Foo(5,3)。

再提一點,作為 .NET 程序的慣用習慣,推薦再重寫一下 == 和 != 操作符。

點評區

這個問題其實非常經典, Equals 和 GetHashCode 到底是什么關系呢?

我個人認為:在復雜類型的比較中, GetHashCode 永遠是一等公民,Equals 才是二等公民,先判斷 HashCode 是否一致,在不一致的情況下再看 Equals 是否一致?最終判斷對象是否相等。

還有一點值得注意的是,GetHashCode 的實現一定要高效,完成理論上的 O(1) 復雜度,否則在 HashSet,Dictioanry 場景下會死的很慘,參考 HashSet 的 Contains 。

原文鏈接:https://stackoverflow.com/questions/371328/why-is-it-important-to-override-gethashcode-when-equals-method-is-overridden?rq=1

總結

以上是生活随笔為你收集整理的NET问答: 重写了 Equals,还有必要重写 GetHashCode 吗?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。