La documentazione VS2005 Guidelines for Overloading Equals() and Operator == (C# Programming Guide) stati in parteQuando dovrebbe essere una classe .NET Override()? Quando non dovrebbe?
Override == operatore nei tipi non immutabili non è raccomandato.
La più recente .NET Framework 4 documentazione Guidelines for Implementing Equals and the Equality Operator (==) omette questa affermazione, anche se un posto in Content Community ripete l'affermazione e riferimenti alla documentazione più vecchio.
Sembra che è ragionevole ignorare Equals() almeno per alcune classi mutabili banali, come
public class ImaginaryNumber
{
public double RealPart { get; set; }
public double ImaginaryPart { get; set; }
}
In matematica, due numeri immaginari che hanno la stessa parte reale e la stessa parte immaginaria sono di fatto uguale nel momento in cui viene testata l'uguaglianza. Non è corretto affermare che si tratta di non uguale a, il che accadrebbe se oggetti separati con lo stesso RealPart e ImaginaryPart fossero Equals() non sovrascritti.
D'altra parte, se si esegue l'override di Equals(), è necessario anche eseguire l'override di GetHashCode(). Se un ImaginaryNumber che sostituisce Equals() e GetHashCode() viene inserito in un HashSet e un'istanza mutabile modifica il suo valore, quell'oggetto non sarà più trovato nell'HashSet.
MSDN non corretto per rimuovere le linee guida per non sovrascrivere Equals()
e operator==
per tipi non immutabili?
È ragionevole sovrascrivere Equals() per i tipi mutabili in cui "nel mondo reale" l'equivalenza di tutte le proprietà significa che gli oggetti stessi sono uguali (come con ImaginaryNumber
)?
Se è ragionevole, qual è il modo migliore per gestire la potenziale mutabilità mentre un'istanza di un oggetto partecipa a un HashSet o qualcos'altro che si basa su GetHashCode() non sta cambiando?
UPDATE
Proprio imbattuto in questo in MSDN
In genere, si implementa l'uguaglianza valore quando gli oggetti del tipo sono dovrebbero essere aggiunto a una raccolta di qualche tipo, o quando il loro lo scopo principale è quello di memorizzare un insieme di campi o proprietà. È possibile basare la definizione di uguaglianza valore su un confronto di tutti i campi e le proprietà di nel tipo oppure basare la definizione su un sottoinsieme . Ma in entrambi i casi, e in entrambe le classi e le strutture, l'implementazione dovrebbe seguire le cinque garanzie di equivalenza:
Io non credo che sia ragionevole per 'ImaginaryNumber' essere un tipo mutabile. –
In realtà, dovresti probabilmente implementare ImaginaryNumber come un tipo di valore immutabile (struct). – Joe
Davvero? Perché? Tutti gli altri numeri sono mutabili. –