溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

NET中重寫(xiě)了Equals還有必要重寫(xiě)GetHashCode的示例分析

發(fā)布時(shí)間:2021-09-18 11:00:39 來(lái)源:億速云 閱讀:113 作者:柒染 欄目:編程語(yǔ)言

NET中重寫(xiě)了Equals還有必要重寫(xiě)GetHashCode的示例分析,相信很多沒(méi)有經(jīng)驗(yàn)的人對(duì)此束手無(wú)策,為此本文總結(jié)了問(wèn)題出現(xiàn)的原因和解決方法,通過(guò)這篇文章希望你能解決這個(gè)問(wèn)題。

咨詢(xún)區(qū)

  • 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,請(qǐng)問(wèn)在重寫(xiě) GetHashCode() 方法時(shí)我該用哪一種實(shí)現(xiàn)呢?

  • base.GetHashCode();

  • this.FooId.GetHashCode();

 

回答區(qū)

  • Marc Gravell

如果你的 item 要作為 DictionaryHashSet 中的key時(shí),那重寫(xiě) GetHashCode() 簡(jiǎn)直就是剛需,因?yàn)榧蠒?huì)根據(jù) item 的 hashcode 對(duì) item 進(jìn)行分組,如果兩個(gè) item 的 hashcode 不一樣,那么 equals 將永遠(yuǎn)不會(huì)被調(diào)用,GetHashCode() 方法應(yīng)該要體現(xiàn) Equals 的邏輯,比較方式大概如下:

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

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

再回到你的場(chǎng)景,用 return FooId 來(lái)作為 GetHashCode() 的實(shí)現(xiàn)是合理的。

不過(guò)作為一般場(chǎng)景,當(dāng) item 中有多個(gè)屬性,推薦的做法是組合多個(gè)屬性,代碼如下:


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 實(shí)現(xiàn)也解決了一個(gè)經(jīng)典的 對(duì)角線(xiàn)沖突 問(wèn)題,比如說(shuō):new Foo(3,5) != new Foo(5,3)

再提一點(diǎn),作為 .NET 程序的慣用習(xí)慣,推薦再重寫(xiě)一下 ==!= 操作符。

 

點(diǎn)評(píng)區(qū)

這個(gè)問(wèn)題其實(shí)非常經(jīng)典, EqualsGetHashCode 到底是什么關(guān)系呢?

我個(gè)人認(rèn)為:在復(fù)雜類(lèi)型的比較中, GetHashCode 永遠(yuǎn)是一等公民,Equals 才是二等公民,先判斷 HashCode 是否一致,在不一致的情況下再看 Equals 是否一致?最終判斷對(duì)象是否相等。

還有一點(diǎn)值得注意的是,GetHashCode 的實(shí)現(xiàn)一定要高效,完成理論上的 O(1) 復(fù)雜度,否則在 HashSet,Dictioanry 場(chǎng)景下會(huì)死的很慘,參考 HashSet 的 Contains 。

NET中重寫(xiě)了Equals還有必要重寫(xiě)GetHashCode的示例分析    

看完上述內(nèi)容,你們掌握NET中重寫(xiě)了Equals還有必要重寫(xiě)GetHashCode的示例分析的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI