2009-08-03 8 views

risposta

26

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.

+1

+1 Molto chiaro e conciso. –

1

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! =.

1

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à.

5

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.

1

sarebbe opportuno, come sarebbe inaspettata se:

if (foo == bar) 

... si sono comportati in modo diverso a:

if (foo.Equals(bar)) 
+1

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

+0

@supercat un buon esempio è quando si confrontano i tipi nullable, Equals è intelligente e controlla HasValue per ogni lato. – Gary

+0

@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

1

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.

2

Oltre a tutte le risposte già disponibili, non dimenticare di garantire che lo standard GetHashCode() sia coerente.

1

in A.Uguale (B) A non può essere nullo in A == B può essere nullo

1

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.

+1

È possibile utilizzare 'Object.ReferenceEquals' per controllare in modo specifico l'uguaglianza di riferimento. –

+0

Aha, grazie Sebastian - Non lo sapevo. –

+1

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

Problemi correlati