Operatori di uguaglianza: verificare se due oggetti sono uguali o meno
Gli operatori ==
(uguaglianza) e !=
(disuguaglianza) controllano se i relativi operandi sono uguali oppure no. I tipi valore sono uguali quando il contenuto è uguale. I tipi di riferimento sono uguali quando le due variabili fanno riferimento alla stessa risorsa di archiviazione.
Operatore di uguaglianza ==
L'operatore di uguaglianza ==
restituisce true
se gli operandi sono uguali, false
in caso contrario.
Uguaglianza dei tipi valore
Gli operandi dei tipi valore predefiniti sono uguali se i relativi valori sono uguali:
int a = 1 + 2 + 3;
int b = 6;
Console.WriteLine(a == b); // output: True
char c1 = 'a';
char c2 = 'A';
Console.WriteLine(c1 == c2); // output: False
Console.WriteLine(c1 == char.ToLower(c2)); // output: True
Nota
Per gli operatori ==
, <
, >
, <=
e >=
, se uno degli operandi non è un numero (Double.NaN oppure Single.NaN) il risultato dell'operazione è false
. Questo significa che il valore NaN
non è maggiore di, minore di, né uguale a qualsiasi altro valore double
(o float
), incluso NaN
. Per altre informazioni ed esempi, vedere l'articolo di riferimento per Double.NaN o Single.NaN.
Due operandi dello stesso tipo enum sono uguali se i valori corrispondenti del tipo integrale sottostante sono uguali.
I tipi struct definiti dall'utente non supportano l'operatore ==
per impostazione predefinita. Per supportare l'operatore ==
, un tipo struct definito dall'utente deve eseguirne l'overload.
Gli operatori ==
e !=
sono supportati dalle tuple C#. Per altre informazioni, vedere la sezione Uguaglianza delle tuple nell'articolo Tipi di tupla.
Uguaglianza dei tipi riferimento
Per impostazione predefinita, due operandi di tipo riferimento non record sono uguali se fanno riferimento allo stesso oggetto:
public class ReferenceTypesEquality
{
public class MyClass
{
private int id;
public MyClass(int id) => this.id = id;
}
public static void Main()
{
var a = new MyClass(1);
var b = new MyClass(1);
var c = a;
Console.WriteLine(a == b); // output: False
Console.WriteLine(a == c); // output: True
}
}
Come illustrato nell'esempio, i tipi riferimento definiti dall'utente supportano l'operatore ==
per impostazione predefinita. Tuttavia, un tipo riferimento può eseguire l'overload dell'operatore ==
. Se un tipo riferimento esegue l'overload dell'operatore ==
, usare il metodo Object.ReferenceEquals per verificare se due riferimenti di quel tipo fanno riferimento allo stesso oggetto.
Uguaglianza dei tipi di record
I tipi di record supportano gli operatori ==
e !=
che per impostazione predefinita forniscono la semantica di uguaglianza dei valori. Ovvero, due operandi di record sono uguali quando entrambi sono null
o i valori corrispondenti di tutti i campi e le proprietà implementate automaticamente sono uguali.
public class RecordTypesEquality
{
public record Point(int X, int Y, string Name);
public record TaggedNumber(int Number, List<string> Tags);
public static void Main()
{
var p1 = new Point(2, 3, "A");
var p2 = new Point(1, 3, "B");
var p3 = new Point(2, 3, "A");
Console.WriteLine(p1 == p2); // output: False
Console.WriteLine(p1 == p3); // output: True
var n1 = new TaggedNumber(2, new List<string>() { "A" });
var n2 = new TaggedNumber(2, new List<string>() { "A" });
Console.WriteLine(n1 == n2); // output: False
}
}
Come illustrato nell'esempio precedente, per i membri di tipo riferimento non record i relativi valori di riferimento vengono confrontati, non le istanze a cui si fa riferimento.
Uguaglianza di stringhe
Due operandi stringa sono uguali quando entrambi sono null
o entrambe le istanze di stringa sono della stessa lunghezza e contengono caratteri identici in ogni posizione di carattere:
string s1 = "hello!";
string s2 = "HeLLo!";
Console.WriteLine(s1 == s2.ToLower()); // output: True
string s3 = "Hello!";
Console.WriteLine(s1 == s3); // output: False
I confronti di uguaglianza tra stringhe sono confronti ordinali con distinzione tra maiuscole e minuscole. Per altre informazioni sul confronto di stringhe, vedere Come confrontare stringhe in C#.
Delegare l'uguaglianza
Due operandi delegati dello stesso tipo di runtime sono uguali quando entrambi sono null
o i relativi elenchi di chiamate hanno la stessa lunghezza e voci uguali in ogni posizione:
Action a = () => Console.WriteLine("a");
Action b = a + a;
Action c = a + a;
Console.WriteLine(object.ReferenceEquals(b, c)); // output: False
Console.WriteLine(b == c); // output: True
Per altre informazioni, vedere la sezione Delegare gli operatori di uguaglianza dell'articolo Specifiche del linguaggio C#.
I delegati prodotti dalla valutazione di espressioni lambda semanticamente identiche non sono uguali, come mostra l'esempio seguente:
Action a = () => Console.WriteLine("a");
Action b = () => Console.WriteLine("a");
Console.WriteLine(a == b); // output: False
Console.WriteLine(a + b == a + b); // output: True
Console.WriteLine(b + a == a + b); // output: False
Operatore di disuguaglianza !=
L'operatore di disuguaglianza !=
restituisce true
se gli operandi sono diversi, false
in caso contrario. Per gli operandi dei tipi predefiniti, l'espressione x != y
produce lo stesso risultato dell'espressione !(x == y)
. Per altre informazioni sull'uguaglianza dei tipi, vedere la sezione Operatore di uguaglianza.
Nell'esempio seguente viene illustrato l'uso dell'operatore !=
:
int a = 1 + 1 + 2 + 3;
int b = 6;
Console.WriteLine(a != b); // output: True
string s1 = "Hello";
string s2 = "Hello";
Console.WriteLine(s1 != s2); // output: False
object o1 = 1;
object o2 = 1;
Console.WriteLine(o1 != o2); // output: True
Overload degli operatori
Un tipo definito dall'utente può eseguire l'overload degli operatori ==
e !=
. Se un tipo esegue l'overload di uno dei due operatori, deve eseguire l'overload anche dell'altro operatore.
Un tipo di record non può eseguire in modo esplicito l'overload degli operatori ==
e !=
. Se è necessario modificare il comportamento degli operatori ==
e !=
per il tipo di record T
, implementare il metodo IEquatable<T>.Equals con la firma seguente:
public virtual bool Equals(T? other);
Specifiche del linguaggio C#
Per altre informazioni, vedere la sezione Operatori relazionali e di test del tipo della specifica del linguaggio C#.
Per altre informazioni sull'uguaglianza dei tipi di record, vedere la sezione Membri di uguaglianza della nota sulla proposta di funzionalità dei record.