你說得對,這是一個很大的鍋爐板代碼,你需要單獨實現的一切。
我會推薦:
- 如果你要實現價值平等可言,覆蓋
GetHashCode
和Equals(object)
- 用於創建==超載和實施IEquatable<T>
沒有做,可能會導致非常意外的行爲
- 我會始終貫徹
IEquatable<T>
如果你覆蓋Equals(object)
和GetHashCode
- 我只有正確重載==操作符更很少
- 實現平等啓封類是棘手的,而且還可以產生令人驚訝的/不希望的結果。如果您需要層次結構中的類型相等,請執行
IEqualityComparer<T>
表示您感興趣的比較。
- 可變類型的平等通常是一個壞主意,因爲兩個對象可以相等,然後不等。如果一個對象在用作哈希表中的關鍵字後發生了變化(以影響等式的方式),您將無法再次找到它。
- 一些鍋爐板的結構略有不同...但像馬克,我很少寫自己的結構。
這裏是一個示例實現:
using System;
public sealed class Foo : IEquatable<Foo>
{
private readonly string name;
public string Name { get { return name; } }
private readonly int value;
public int Value { get { return value; } }
public Foo(string name, int value)
{
this.name = name;
this.value = value;
}
public override bool Equals(object other)
{
return Equals(other as Foo);
}
public override int GetHashCode()
{
int hash = 17;
hash = hash * 31 + (name == null ? 0 : name.GetHashCode());
hash = hash * 31 + value;
return hash;
}
public bool Equals(Foo other)
{
if ((object) other == null)
{
return false;
}
return name == other.name && value == other.value;
}
public static bool operator ==(Foo left, Foo right)
{
return object.Equals(left, right);
}
public static bool operator !=(Foo left, Foo right)
{
return !(left == right);
}
}
是的,這是一個很大的樣板赫克,這很少的實現:(
的==
實施是稍微之間變化效率比它可能低,因爲它會通過呼籲Equals(object)
哪些需要做動態類型檢查...但替代是更多的鍋爐板,如下所示:
public static bool operator ==(Foo left, Foo right)
{
if ((object) left == (object) right)
{
return true;
}
// "right" being null is covered in left.Equals(right)
if ((object) left == null)
{
return false;
}
return left.Equals(right);
}
^^你的每個職位是一個C#學習章節.. :) – Dienekes 2010-12-14 10:08:15
對於第二個代碼塊的2個小建議:1)你不應該把==(對象)從== =='移動到通用'Equals'嗎?因此,即使對於通用的「Equals」方法,速度(當然這取決於,但假設最壞的情況)會檢查引用相等性嗎? 2)你不需要在'=='中進行第二次空的檢查'(對象)right == null',因爲你基本上是在泛型'Equals'中做的。看到我的帖子.. – nawfal 2012-12-16 20:53:24
@nawfal:我認爲在通用的'Equals'情況下做這件事並沒有多大意義 - 無論如何,在* *爲true的情況下它會很快,對於它的情況*不是真的,它增加了一個額外的檢查沒有任何好處。至於零部分 - 這將需要再次檢查動態類型。是的,你可以爲兩者爭辯 - 但我很滿意我兩年前寫的東西...... – 2012-12-16 20:58:04