c#: ReferenceEquals, Equals, Operatore ==
- Il metodo ReferenceEquals verifica le uguaglianze per riferimento
- Il metodo Equals verifica le uguaglianze per valore
- l’operatore “==” a volte per riferimento e a volte per valore.
Ecco qualche esempio:
Se dichiariamo a e b in questo modo:
System.Object a = new System.Object(); System.Object b = a; |
a e b sono riferimento allo stesso oggetto. Per avere la prova sul campo basta eseguire questo codice:
class Program { static void Main(string[] args) { ObjectClass o1 = new ObjectClass(); ObjectClass o2 = o1; o1.Value = 3; Console.WriteLine("o1: {0}", o1.Value); Console.WriteLine("o2: {0}", o2.Value); o2.Value = 5; Console.WriteLine("o1: {0}", o1.Value); Console.WriteLine("o2: {0}", o2.Value);</code> Console.WriteLine("ReferenceEquals: {0}", System.Object.ReferenceEquals(o1, o2)); } class ObjectClass { private int value;</code> public int Value { get { return this.value; } set { this.value = value; } } } } |
Il risultato è:
o1: 3
o2: 3
o1: 5
o2: 5
ReferenceEquals: True
Equals: True
==: True
quindi modificare uno dei due oggetti significa modificare anche l’altro. Il metodo System.Object.ReferenceEquals verifica appunto l’uguaglianza per riferimento di due oggetti.
Se invece li dichiariamo così:
ObjectClass o1 = new ObjectClass();
ObjectClass o2 = new ObjectClass();
o1.Value = 3;
o2.Value = 3;
Console.WriteLine("ReferenceEquals: {0}", System.Object.ReferenceEquals(o1, o2));
Console.WriteLine("Equals: {0}", System.Object.Equals(o1, o2));
Console.WriteLine("==: {0}", o1 == o2);
il risultato è:
ReferenceEquals: False
Equals: False
==: False
- ReferenceEquals è False perche o1 e o2 sono due oggetti separati, che nulla hanno in comune se non il valore uguale.
- Equals è False perchè sto confrontando due oggetti che ho creato io, e in cui non ho specificato nessun ovverride per il metodo Equals.
- == è false perchè in questo caso si comporta come ReferenceEquals
Un esempio interessante è questo, sulle stringhe:
String s1 = "pippo";
String s2 = "pippo";
Console.WriteLine("Risultato ReferenceEquals: {0}", System.Object.ReferenceEquals(s1, s2));
Console.WriteLine("Risultato Equals: {0}", System.Object.Equals(s1, s2));
Console.WriteLine("Risultato ==: {0}", s1 == s2);
il risultato è:
Risultato ReferenceEquals: True
Risultato Equals: True
Risultato ==: True
- ReferenceEquals restituisce True perche s1 e s2 sono riferimento allo stesso oggetto. Così funziona c# quando si dichiarano più stringhe con lo stesso valore.
- Equals resituisce True perchè sto confrontando un’oggetto con se stesso
- == restituisce True perchè in questo caso si comporta come Equals
Invece:
String s1 = "pippo";
String s2 = String.Copy(s1);
Console.WriteLine("Risultato ReferenceEquals: {0}", System.Object.ReferenceEquals(s1, s2));
Console.WriteLine("Risultato Equals: {0}", System.Object.Equals(s1, s2));
Console.WriteLine("Risultato ==: {0}", s1 == s2);
(il metodo String.Copy crea una nuova istanza con valore uguale a quella in input)
genera questo risultato:
Risultato ReferenceEquals: False
Risultato Equals: True
Risultato ==: True
- ReferenceEquals restituisce false, perchè s1 e s2 non puntano allo stesso oggetto
- Equals restituisce True, perchè s1 e s2 hanno lo stesso valore
- == restituisce True perchè in questo caso si comporta come Equals
L’operatore ==, al contrario del Java, può essere usato per il confronto fra stringhe. Ma vediamo cosa succede se facciamo un downgrade di String a Object:
String s1 = "pippo";
String s2 = String.Copy(s1);
Console.WriteLine("Risultato ReferenceEquals: {0}", System.Object.ReferenceEquals(s1, s2));
Console.WriteLine("Risultato ReferenceEquals: {0}", System.Object.ReferenceEquals((Object)s1, (Object)s2));
Console.WriteLine("Risultato Equals: {0}", System.Object.Equals(s1, s2));
Console.WriteLine("Risultato Equals: {0}", System.Object.Equals((Object)s1, (Object)s2));
Console.WriteLine("Risultato ==: {0}", s1 == s2);
Console.WriteLine("Risultato ==: {0}", (Object)s1 == (Object)s2);
Il risultato è:
Risultato ReferenceEquals: False
Risultato ReferenceEquals: False
Risultato Equals: True
Risultato Equals: True
Risultato ==: True
Risultato ==: False
Il suo comportamento è definito dall’msdn di mamma Microsoft:
For predefined value types, the equality operator (==) returns true if the values of its operands are equal, false otherwise. For reference types other than string, == returns true if its two operands refer to the same object. For the string type, == compares the values of the strings.
Ovvero: l’uguaglianza è verificata per valore se è verificata fra tipi predefiniti e stringhe, in tutti gli altri casi è per riferimento.
Leave a Reply