簡體   English   中英

我需要在引用類型上覆蓋 GetHashCode() 嗎?

[英]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團隊的人可以回答這個問題。

至於其他問題,里德實際上打敗了我的沖擊: GetHashCodeEquals MSDN 頁面用更多的血腥細節描述它,以防萬一。

暫無
暫無

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

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