Differenza tra == e Equals
Scritto da
Roberto Albano il
lunedì 11 aprile 2011
•
Linguaggio:
• Livello: 100
Molti pensano che nella comparazione tra due oggetti si possa
utilizzare in maniera indifferente sia l'operatore di uguaglianza
'==' sia il metodo Equals (presente già dalla classe
object).
Questo in realtà non è vero dato che, in base al tipo di
comparazione, si possono ottenere risultati diversi.
Partiamo subito con un esempio:
int i1 = 100;
int i2 = 100;
bool b1 = ( i1 == i2 ); // true
bool b2 = ( i1.Equals(i2) ); // true
StringBuilder sb1 = new StringBuilder("prova");
StringBuilder sb2 = new StringBuilder("prova");
bool b3 = ( sb1 == sb2 ); // false
bool b4 = ( sb1.Equals(sb2) ); // true
Questo succede perché la comparazione tra value
types (come nel caso degli int) avviene
sempre a livello di valore, quindi '==' ed Equals si
comportano allo stesso modo, mentre nella comparazione tra
reference types (come nel caso della
classe StringBuilder) questo avviene a livello di
puntamento per '==' e a livello di valore per Equals.
Di fatto Equals è un metodo della classe object, che
può essere sottoposto ad "override" (cioè a ridefinizione)
nelle classi in cui si abbia la necessità di definire l'uguaglianza
in maniera diversa.
public override bool Equals(object obj)
{
// ...
}
Quindi nella classe StringBuilder il metodo Equals
verifica il valore (in questo caso della stringa) presente
nell'istanza mentre l'operatore '==' verifica se
fisicamente gli oggetti della comparazione rappresentino
effettivamente lo stesso oggetto (ovvero se puntano di fatto allo
stesso spazio di memoria).
Qualcuno noterà subito che se eseguiamo un codice del
genere:
string s1 = "prova";
string s2 = "prova";
bool b5 = ( s1 == s2 ); // true
bool b6 = ( s1.Equals(s2) ); // true
otterremo sempre un'uguaglianza, anche se la classe
string è, di fatto, un reference
type.
In questo caso nella classe string è stato fatto un
"override" dell'operatore '==':
public static bool operator == (object obj1, object obj2)
{
// ...
}
(per completezza diciamo che nella classe string è
stato ridefinito in maniera analoga anche l'operatore
'!=')
Teniamo sempre bene a mente la possibilità di dover eseguire
questi "override" quando sviluppiamo le nostre
classi.
Tags: C#,CLR