簡體   English   中英

在C#中簡化覆蓋等於(),GetHashCode()以獲得更好的可維護性

[英]Simplify Overriding Equals(), GetHashCode() in C# for Better Maintainability

我經常發現我的自我重寫Equals()GetHashCode()來實現具有相同屬性值的業務對象相等的語義。 這會導致代碼重復寫入並且易於維護(屬性被添加,並且一個/兩個覆蓋都不會更新)。

代碼最終看起來像這樣(歡迎對實現的評論):

public override bool Equals(object obj)
{
    if (object.ReferenceEquals(this, obj)) return true;

    MyDerived other = obj as MyDerived;

    if (other == null) return false;

    bool baseEquals = base.Equals((MyBase)other);
    return (baseEquals && 
        this.MyIntProp == other.MyIntProp && 
        this.MyStringProp == other.MyStringProp && 
        this.MyCollectionProp.IsEquivalentTo(other.MyCollectionProp) && // See http://stackoverflow.com/a/9658866/141172
        this.MyContainedClass.Equals(other.MyContainedClass));
}

public override int GetHashCode()
{
    int hashOfMyCollectionProp = 0;
    // http://computinglife.wordpress.com/2008/11/20/why-do-hash-functions-use-prime-numbers/
    // BUT... is it worth the extra math given that elem.GetHashCode() should be well-distributed?
    int bitSpreader = 31; 
    foreach (var elem in MyCollectionProp)
    {
        hashOfMyCollectionProp = spreader * elem.GetHashCode();
        bitSpreader *= 31;
    }
    return base.GetHashCode() ^ // ^ is a good combiner IF the combined values are well distributed
        MyIntProp.GetHashCode() ^ 
        (MyStringProp == null ? 0 : MyStringProp.GetHashValue()) ^
        (MyContainedClass == null ? 0 : MyContainedClass.GetHashValue()) ^
        hashOfMyCollectionProp;
}

我的問題

  1. 實施模式是否合理?
  2. 鑒於貢獻組件值分布均勻,是否足夠? 在組合集合元素時,我需要乘以31到N,因為它們的散列分布均勻嗎?
  3. 似乎可以將此代碼抽象為使用反射來確定公共屬性的代碼,構建與手動編碼解決方案匹配的表達式樹,並根據需要執行表達式樹。 這種方法看起來合理嗎? 某處有現有的實施嗎?

MSDN實際上並沒有說“不要為可變類型重載Equals等”。 它曾經說過,但現在它說:

定義類或結構時,您可以決定是否為類型創建值相等(或等效)的自定義定義。 通常,當期望將類型的對象添加到某種類型的集合時,或者當它們的主要目的是存儲一組字段或屬性時,實現值相等。

http://msdn.microsoft.com/en-us/library/dd183755.aspx

然而,當對象參與散列集合( Dictionary<T,U>HashSet<T>等)時,存在圍繞哈希碼的穩定性的復雜性。

我決定選擇兩全其美,如下所述:

https://stackoverflow.com/a/9752155/141172

我發現我的自我經常覆蓋Equals()和GetHashCode()

  • MSDN說:不要為Equals等過載可變類型

鑒於貢獻組件值分布均勻,是否足夠?

  • 是的,但嘿並不總是分布很好。 考慮int屬性。 建議使用一些(小)素數進行移位。

也許我在這里很困惑,但是在GetHashCode覆蓋中,on null check不應該返回1而不是0?

所以

MyStringProp == null ? 0 : MyStringProp.GetHashValue()

應該

MyStringProp == null ? 1 : MyStringProp.GetHashValue()

暫無
暫無

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

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