[英]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;
}
}
其中firstItem
、 secondItem
等是對哈希碼有貢獻的項目。 (也可以使用更大的質數代替 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.