![](/img/trans.png)
[英]If I override ToString, do i need to override Equals and GetHashCode as well?
[英]Do I need to override GetHashCode() on reference types?
我在 StackOverflow 上閱讀了關於GetHashCode
大多數問題。 但我仍然不確定是否必須在引用類型上覆蓋GetHashCode
。 我從某人在另一個問題中的回答中了解到以下內容:
Object.GetHashCode() 使用 System.Object 類中的內部字段來生成哈希值。 創建的每個對象都會分配一個唯一的對象鍵,在創建時存儲為整數。 這些鍵從 1 開始並在每次創建任何類型的新對象時遞增。
如果在 .NET Framework 3.5 中仍然如此(有人可以確認嗎?),那么我看到的引用類型默認實現的唯一問題是散列代碼的分布很差。
我將打破我的問題:
a) 因此,如果在Dictionary
使用GetHashCode
或默認實現是否執行得很好,它也建議覆蓋GetHashCode
?
b)我有引用類型,因為它們具有唯一標識它們的字段,所以很容易做到,但是那些所有成員也是引用類型的引用類型呢? 我應該在那里做什么?
如果重寫Object.Equals(),則只需要在引用類型上覆蓋GetHashCode()。
原因很簡單 - 通常,2個引用總是不同的(a.Equals(b)== false,除非它們是同一個對象)。 在這種情況下,GetHashCode()的默認實現將提供2個不同的哈希值,因此一切都很好。
但是,如果重寫Equals(),則無法保證此行為。 如果兩個對象相等(根據Equals()),則需要保證它們與GetHashCode具有相同的哈希碼,因此您應該覆蓋它。
看看我在文章中留下的評論: GetHashCode擴展方法
我剛剛做了一個樣本測試,我沒看到它從1開始是如何增加的。
for (int i = 0; i < 16; i++)
{
object obj = new object();
Console.Write(obj.GetHashCode() + " ");
}
結果如下:
45653674 41149443 39785641 45523402 35287174 44419000 52697953 22597652
10261382 59109011 42659827 40644060 17043416 28756230 18961937 47980820
事實上,使用Reflector,我只能看到這個:
internal static extern int InternalGetHashCode(object obj);
所以它真正發生的事情對我來說是個謎(可能有一種模式,但我不打算在這一點上深入挖掘 - 可能是某種“偽隨機數” 算法 ?)。 來自CLR團隊的人可以回答這個問題。
至於其他問題,里德實際上打敗了我的沖擊: GetHashCode
和Equals
。 MSDN 頁面用更多的血腥細節描述它,以防萬一。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.