Nessuna delle risposte qui è davvero azzeccata per me. Dato che hai già detto che non puoi usare Id
per l'uguaglianza e hai bisogno di usare un pacchetto di proprietà, ecco un modo migliore per farlo. Nota: non considero questo in generale il modo migliore per implementare Equals
e GetHashCode
. Questa è una versione migliore del codice dell'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;
}
Vedi this answer by Jon Skeet per alcuni il ragionamento dietro questo. L'uso di xor non va bene perché vari set di dati possono finire con lo stesso hash. Questo metodo wrap-around con i numeri primi (i valori seme di 19 e 31 sopra, o altri valori scelti) fa un lavoro migliore di segmentazione in "bucket" che hanno ciascuna collisioni.
Se uno qualsiasi dei vostri valori può essere nullo, vi incoraggio a riflettere attentamente su come devono essere confrontati. Potresti usare la valutazione nulla di cortocircuito e forse l'operatore di coalescenza nulla. Ma assicurati che se i valori nulli debbano essere confrontati come uguali, assegni codici hash diversi alle diverse proprietà nullable quando sono nulli.
Inoltre, non sono convinto che l'implementazione di Equals
abbia senso. Quando due oggetti vengono confrontati per l'uguaglianza, prima vengono confrontati i loro valori GetHashCode
. Solo se questi sono diversi è il metodo Equals
eseguito (in modo che se due oggetti che hanno hash sullo stesso valore siano diversi, questo verrà rilevato).Poiché l'implementazione di GetHashCode
non fa riferimento a base
, non ha senso il metodo Equals
.
Correlato: http://stackoverflow.com/questions/2326288/implementing-ddd-entity-class-in-c –
Non è possibile utilizzare i risultati di GetHashCode come unico determinante in Equals - i codici hash possono essere lo stesso quando gli oggetti sono diversi. Faresti molto meglio a confrontare i tuoi ID in Equals. Per ulteriori informazioni, vedere [Perché è importante sovrascrivere GetHashCode quando il metodo Equals è sovrascritto in C#?] (Http://stackoverflow.com/questions/371328/why-is-it-important-to-override-gethashcode- when-equals-method-is-overriden-in-c) –
Si dovrebbe tenere presente che GetHashCode() è utilizzato principalmente nel codice in cui le prestazioni sono importanti (elenchi con ricerche O (1), ecc.). La tua implementazione è già piuttosto lenta, ma potresti già accelerarla senza cambiare molto: 'return (" MyClass "+ this.Id) .GetHashCode();' (solo qualcosa che potresti voler ricordare con GetHashCode) – Aidiakapi