這裏沒有任何答案真的給我留下了深刻的印象。既然你已經說過你不能使用Id
進行平等,並且你需要使用一組屬性,這裏有一個更好的方法來做到這一點。注意:我並不認爲這是實施Equals
和GetHashCode
的最佳方法。這是OP代碼的更好版本。
public override bool Equals(object obj)
{
var myClass = obj as MyClass;
if (null != myClass)
{
// Order these by the most different first.
// That is, whatever value is most selective, and the fewest
// instances have the same value, put that first.
return this.Id == myClass.Id
&& this.Name == myClass.Name
&& this.Quantity == myClass.Quantity
&& this.Color == myClass.Color;
}
else
{
// Not sure this makes sense!
return base.Equals(obj);
}
}
public override int GetHashCode()
{
int hash = 19;
unchecked { // allow "wrap around" in the int
hash = hash * 31 + this.Id; // assuming integer
hash = hash * 31 + this.Name.GetHashCode();
hash = hash * 31 + this.Quantity; // again assuming integer
hash = hash * 31 + this.Color.GetHashCode();
}
return hash;
}
請參閱this answer by Jon Skeet瞭解一些背後的原因。使用異或並不好,因爲各種數據集最終會導致相同的散列。帶素數的這個環繞式方法(上面的19和31的種子值,或者您選擇的其他值)可以更好地分割成每個幾乎沒有碰撞的「桶」。
如果您的任何值可以爲空,我鼓勵您仔細考慮應該如何比較。也許你可以使用短路零位評估和零合併算子。但請確保如果空值應該相等,則當它們爲空時,您可以將不同的哈希碼分配給不同的可空屬性。
此外,我不相信你的Equals
實施是有道理的。當比較兩個對象時,首先比較它們的GetHashCode
值。只有那些不同的是Equals
方法運行(以便如果兩個哈希到相同值的對象不同,這將被檢測到)。由於您的GetHashCode
實施不涉及base
,因此您的Equals
方法無法做到這一點。
相關:http://stackoverflow.com/questions/2326288/implementing-ddd-entity-class-in-c – 2010-03-02 12:48:16
你不能使用GetHashCode的結果作爲Equals中唯一的行列式 - 哈希碼可以是當物體不同時相同。在Equals中比較你的ID會更好。有關這方面的更多信息,請參閱[在C#中等式方法被重寫時覆蓋GetHashCode爲什麼非常重要?](http://stackoverflow.com/questions/371328/why-is-it-important-to-override-gethashcode-當你在等待方法被覆蓋在C) – 2010-03-02 12:52:41
你應該記住,GetHashCode()主要用於代碼性能是重要的(列表O(1)查找等)。你的實現已經很慢了,但是你可以在不改變太多的情況下加快速度:'return(「MyClass」+ this.Id).GetHashCode();'(你可能想要用GetHashCode來記住) – Aidiakapi 2011-09-13 07:30:20