簡體   English   中英

GetHashCode 用於保存字符串字段的類型

[英]GetHashCode for a type holding string fields

我有這個類,在那里我覆蓋了 Object Equals:

public class Foo
{
    public string string1 { get; set; }

    public string string2 { get; set; }

    public string string3 { get; set; }

    public override bool Equals(object other)
    {
        if (!(other is Foo)) return false;
        Foo otherFoo = (other as Foo);

        return otherFoo.string1 == string1 && otherFoo.string2 == string2 && otherFoo.string3 == string3;
    }
}

我收到一個警告“覆蓋 object.equals 但不覆蓋 object.gethashcode”,我理解覆蓋 GetHashCode 的必要性,以便我的類型根據可散列類型進行操作。

據我研究,為了使此代碼唯一,通常使用 XOR 運算符,或者涉及素數乘法。 所以,根據我的消息來源, 來源1源2我正在考慮我的GesHashCode覆蓋方法這兩個選項。

1:

public override int GetHashCode() {
        return string1.GetHashCode() ^ string2.GetHashCode() ^ string3.GetHashCode();
}

2:

public override int GetHashCode() {
        return (string1 + string2 + string3).GetHashCode();
}

我也不確定這種方法是否確保了在我的情況下 GetHashCode 覆蓋的目的,即消除編譯警告,順便確保類型可以在集合中正確處理,我相信這是如果它們持有的值相等被認為是相等的,但是如果在集合中不同實例上出現相等的值,則需要相應地找到每個實例。

在這兩種方法都有效的情況下,我想知道哪一種可能更好以及為什么。

有一個相當簡單但有效的方法來做到這一點:

public override int GetHashCode()
{
    unchecked // Hash code calculation can overflow.
    {
        int hash = 17;

        hash = hash * 23 + firstItem.GetHashCode();
        hash = hash * 23 + secondItem.GetHashCode();

        // ...and so on for each item.

        return hash;
    }
}

其中firstItemsecondItem等是對哈希碼有貢獻的項目。 (也可以使用更大的質數代替 17 和 23,但實際上並沒有太大區別。)

但是請注意,如果您使用的是 .Net Core 3.1,則可以改為執行以下操作

public override int GetHashCode() => HashCode.Combine(firstItem, secondItem, ...etc);

順便說一句,如果有人想看看HashCode.Combine()的實現,它在這里

它比我發布的代碼復雜得多。 :)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM