[英]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;
}
我的問題
MSDN實際上並沒有說“不要為可變類型重載Equals等”。 它曾經說過,但現在它說:
定義類或結構時,您可以決定是否為類型創建值相等(或等效)的自定義定義。 通常,當期望將類型的對象添加到某種類型的集合時,或者當它們的主要目的是存儲一組字段或屬性時,實現值相等。
http://msdn.microsoft.com/en-us/library/dd183755.aspx
然而,當對象參與散列集合( Dictionary<T,U>
, HashSet<T>
等)時,存在圍繞哈希碼的穩定性的復雜性。
我決定選擇兩全其美,如下所述:
我發現我的自我經常覆蓋Equals()和GetHashCode()
鑒於貢獻組件值分布均勻,是否足夠?
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.