4 回答

TA貢獻(xiàn)1719條經(jīng)驗(yàn) 獲得超6個(gè)贊
是的,重要的是,您的項(xiàng)目將用作字典中的鍵,或者HashSet<T>
等等 - 因?yàn)檫@是用于(在沒有自定義的情況下IEqualityComparer<T>
)將項(xiàng)目分組到存儲(chǔ)桶中。如果兩個(gè)項(xiàng)的哈希碼不匹配,它們可能永遠(yuǎn)不會(huì)被認(rèn)為是相等的(Equals
將永遠(yuǎn)不會(huì)被調(diào)用)。
該GetHashCode()
方法應(yīng)反映Equals
邏輯; 規(guī)則是:
如果兩個(gè)東西相等(
Equals(...) == true
)那么它們必須返回相同的值GetHashCode()
如果
GetHashCode()
是相等的,它是不必要對他們是相同的; 這是一次碰撞,Equals
將被調(diào)用以查看它是否是真正的平等。
在這種情況下,看起來“ return FooId;
”是一個(gè)合適的GetHashCode()
實(shí)現(xiàn)。如果您正在測試多個(gè)屬性,通常使用下面的代碼組合它們,以減少對角線沖突(即,new Foo(3,5)
具有不同的哈希碼new Foo(5,3)
):
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;}
哦 - 為了方便起見,你也可以考慮提供==
和!=
操作員覆蓋Equals
和GetHashCode
。
當(dāng)你弄錯(cuò)了會(huì)發(fā)生什么事的證明就在這里。

TA貢獻(xiàn)1893條經(jīng)驗(yàn) 獲得超10個(gè)贊
實(shí)際上很難GetHashCode()
正確實(shí)現(xiàn),因?yàn)槌薓arc已經(jīng)提到的規(guī)則之外,哈希代碼在對象的生命周期內(nèi)不應(yīng)該改變。因此,用于計(jì)算哈希碼的字段必須是不可變的。
當(dāng)我使用NHibernate時(shí),我終于找到了解決這個(gè)問題的方法。我的方法是從對象的ID計(jì)算哈希碼。只能通過構(gòu)造函數(shù)設(shè)置ID,因此如果要更改ID,這是非常不可能的,您必須創(chuàng)建一個(gè)具有新ID的新對象,因此需要新的哈希代碼。這種方法最適用于GUID,因?yàn)槟梢蕴峁╇S機(jī)生成ID的無參數(shù)構(gòu)造函數(shù)。

TA貢獻(xiàn)1946條經(jīng)驗(yàn) 獲得超4個(gè)贊
通過重寫Equals,您基本上聲明自己是更了解如何比較給定類型的兩個(gè)實(shí)例的人,因此您很可能是提供最佳哈希碼的最佳候選者。
這是ReSharper如何為您編寫GetHashCode()函數(shù)的示例:
public override int GetHashCode(){ unchecked { var result = 0; result = (result * 397) ^ m_someVar1; result = (result * 397) ^ m_someVar2; result = (result * 397) ^ m_someVar3; result = (result * 397) ^ m_someVar4; return result; }}
正如您所看到的,它只是試圖根據(jù)類中的所有字段猜測一個(gè)好的哈希代碼,但是既然您知道對象的域或值范圍,您仍然可以提供更好的哈希代碼。
- 4 回答
- 0 關(guān)注
- 915 瀏覽
添加回答
舉報(bào)