簡體   English   中英

我應該何時在不可變結構上實現GetHashCode?

[英]When should I implement GetHashCode on an immutable struct?

我在這里閱讀了一些與GetHashCode正確實現相關的問題。 我沒找到的是什么時候應該實現這個方法。

在我的具體情況下,我構建了一個簡單的不可變結構:

public struct MyStruct
{
    private readonly Guid m_X;
    private readonly string m_Y;
    private readonly string m_Z;

    public Guid string X
    {
        get { return m_X; }
    }

    public string Y
    {
        get { return m_Y; }
    }

    public string Z
    {
        get { return m_Z; }
    }

    public MyStruct(Guid x, string y, string z)
    {
        if (x == Guid.Empty) throw new ArgumentException("x cannot be equals to Guid.Empty", "x");
        if (string.IsNullOrEmpty(y)) throw new ArgumentException("y cannot be null or empty", "y");
        if (string.IsNullOrEmpty(Z)) throw new ArgumentException("Z cannot be null or empty", "Z");

        this.m_X = x;
        this.m_Y = y;
        this.m_Z = Z;
    }

    public override int GetHashCode()
    {
        var x = 17;

        x = x * 23 + m_X.GetHashCode();
        x = x * 23 + m_Y.GetHashCode();
        x = x * 23 + m_Z.GetHashCode();

        return x;
    }
}

在這種情況下,我實現了GetHashCode ,但它是強制性的嗎? 是不是基礎對象object.GetHashCode實現本身處理這種情況?

[編輯]一點背景:我有一些字符串要解析並生成。 此字符串是第三方自定義查詢語言的一部分。 該字符串的格式始終為X|Y|Z 我想通過提供這個自定義結構來避免開發人員使用string.Split和字符串連接。 最后,struct將包含這兩個補充方法:

    public override string ToString()
    {
        return m_X.ToString() + "|" + m_Y + "|" + m_Z;
    }

    public static MyString Parse(string stringToParse)
    {
         // implementation omitted
    }

是不是基礎對象.GetHashCode實現本身處理這種情況?

不, ValueType.GetHashCode()實際上正在處理它 - 並且默認實現工作非常糟糕,在大多數情況下僅使用第一個字段。 (在這種情況下,由於字符串引用,你的結構不是“blittable”,所以我不確定它會做什么。只能從字段中的簡單二進制值檢查相等性 - 字符串需要要檢查是否平等。)

對於要用於相等操作的任何值類型(例如,作為字典中的鍵),最好覆蓋GetHashCodeEquals(object) ,以及實現IEquatable<T>以便相等性檢查不需要裝箱。

在不重寫Equals情況下覆蓋GetHashCode 絕對是一個壞主意 - 我很驚訝編譯器沒有警告你。

什么時候應該實現這個方法

考慮到GetHashCode主要用於比較覆蓋,必須在必須實現自己的比較邏輯時使用它。

這可能是一種情況,當你也要定義不完全相同(從內容的角度來看)結構實例的相似性時。 (可以自然地定義為自定義比較邏輯)

可能在類中使用,如字典/哈希中的Keys

可能在散列表中用作鍵的類也必須覆蓋此方法,因為在散列表中用作鍵的對象需要通過此方法生成自己的散列碼

暫無
暫無

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

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