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.

Vedi anche