Oppure è consigliabile farlo? Perché?È necessario sovrascrivere gli operatori == e! = Quando si esegue l'override del metodo Equals? (.NET)
risposta
Vedere guidelines for overriding Equals() and operator==.
Quota:
Per default, l'operatore == test per l'uguaglianza di riferimento per determinare se due riferimenti indicano lo stesso oggetto. Pertanto, i tipi di riferimento non devono implementare l'operatore == per ottenere questa funzionalità. Quando un tipo è immutabile, cioè i dati contenuti nell'istanza non possono essere modificati, l'operatore di overload == per confrontare l'uguaglianza del valore anziché l'uguaglianza di riferimento può essere utile perché, come oggetti immutabili, possono essere considerati uguali a quelli lunghi come hanno lo stesso valore. Non è una buona idea sovrascrivere l'operatore == in tipi non immutabili.
In sostanza:
Se volete == e = a comportarsi come Equals(..)
e !Equals(..)
è necessario implementare gli operatori. In genere lo fai solo con tipi immutabili.
Se si esegue l'override del metodo di uguaglianza e si desidera comunque essere in grado di verificare l'uguaglianza (o la disuguaglianza), è consigliabile sovrascrivere anche i metodi == e! =.
Non è necessario, ma una cosa intelligente da fare.
Se si sta creando un framework e un altro sviluppatore diverso da quello che si utilizzerà l'oggetto, è necessario eseguire l'override di == e! =. In questo modo, quando uno sviluppatore può usarlo, hanno almeno la logica giusta per confrontare i 2 oggetti anziché essere uguali in memoria.
Mi piacerebbe che il tuo == &! = Chiami il tuo metodo di parità.
Vedi Guidelines for Implementing Equals and the Equality Operator (==)
Per Tipi di valore (le strutture) "Attuare == ogni volta che l'override del metodo Equals"
Per i tipi di riferimento (classi), "La maggior parte dei tipi di riferimento, anche quelli che implementano le Equals metodo, non dovrebbe sovrascrivere ==. " L'eccezione è per le classi immutabili e quelle con semantica di valore.
sarebbe opportuno, come sarebbe inaspettata se:
if (foo == bar)
... si sono comportati in modo diverso a:
if (foo.Equals(bar))
Ci sono molti casi in cui 'foo == bar' si comporta diversamente da' foo.Equals (bar) '. Una credenza sbagliata nella loro equivalenza è suscettibile di causare molti problemi piuttosto che riconoscere che non possono sempre comportarsi allo stesso modo e non ci si dovrebbe aspettare [anzi, il Framework ha alcune incongruenze in ciò che significa "Equals" che deriva da un IMHO malriposto desiderio di fallo corrispondere a '==']. – supercat
@supercat un buon esempio è quando si confrontano i tipi nullable, Equals è intelligente e controlla HasValue per ogni lato. – Gary
@Gary: stavo pensando più a cose come 'Decimal'. È utile avere un mezzo di paragone che consideri gli oggetti classificati come uguali se nessuno dei due si trova sopra l'altro, ma è anche utile avere un mezzo per test di uguaglianza che possa riconoscere oggetti ugualmente ordinati (ad esempio 1,0 d e 1,00 d) come distinti. IMHO, tali oggetti dovrebbero produrre risultati di confronto opposti con '==' e '.Equalisti'. – supercat
Non è necessario, nessuno ti ucciderà se non lo fai Fai quello.
Tuttavia, si noti che è spesso più naturale scrivere (A == B) di A.Equal (B). Se fornisci entrambi i metodi, sarà più facile per i consumatori del tuo codice.
Oltre a tutte le risposte già disponibili, non dimenticare di garantire che lo standard GetHashCode()
sia coerente.
in A.Uguale (B) A non può essere nullo in A == B può essere nullo
Ignorare == per chiamare Chiama mi sembra una cattiva idea per i tipi di riferimento. Se si esegue l'override == per chiamare Chiama Equals, non penso che esista un modo per un utente del codice per verificare se due riferimenti a oggetti si riferiscono allo stesso oggetto esatto (rispetto a un oggetto con proprietà uguali).
Se le persone vogliono testare le istanze delle classi per l'uguaglianza di valore, allora sicuramente dovrebbero chiamare Equals, salvando == per testare specificamente l'uguaglianza di riferimento.
È possibile utilizzare 'Object.ReferenceEquals' per controllare in modo specifico l'uguaglianza di riferimento. –
Aha, grazie Sebastian - Non lo sapevo. –
Sebbene sia possibile utilizzare 'Object.ReferenceEquals', è piuttosto goffo. Considero l'uso di C# del token '==' per entrambi gli operatori di overload-uguaglianza-test e di uguaglianza di riferimento come uno dei più grandi errori di progettazione nella lingua. – supercat
+1 Molto chiaro e conciso. –