[英]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”,所以我不確定它會做什么。只能從字段中的簡單二進制值檢查相等性 - 字符串需要要檢查是否平等。)
對於要用於相等操作的任何值類型(例如,作為字典中的鍵),最好覆蓋GetHashCode
和Equals(object)
,以及實現IEquatable<T>
以便相等性檢查不需要裝箱。
在不重寫Equals
情況下覆蓋GetHashCode
絕對是一個壞主意 - 我很驚訝編譯器沒有警告你。
什么時候應該實現這個方法
考慮到GetHashCode
主要用於比較覆蓋,必須在必須實現自己的比較邏輯時使用它。
這可能是一種情況,當你也要定義不完全相同(從內容的角度來看)結構實例的相似性時。 (可以自然地定義為自定義比較邏輯)
它可能在類中使用,如字典/哈希中的Keys
。
可能在散列表中用作鍵的類也必須覆蓋此方法,因為在散列表中用作鍵的對象需要通過此方法生成自己的散列碼
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.