Condividi tramite


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.

È possibile usare l'operatore di corrispondenza dei is criteri come alternativa a un == test quando si esegue il test su un valore costante. L'operatore is usa la semantica di uguaglianza predefinita per tutti i tipi valore e riferimento.

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 o Single.NaN), il risultato dell'operazione è false. Ciò significa che il NaN valore non è maggiore di, minore o uguale a qualsiasi altro double valore (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.

Le tuple C# hanno il supporto predefinito per gli == operatori e != . Per altre informazioni, vedere la sezione Uguaglianza delle tuple nell'articolo Tipi di tupla.

Uguaglianza dei tipi riferimento

Per impostazione predefinita, gli operandi di tipo riferimento, esclusi i 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 vengono confrontati i relativi valori di riferimento, non le istanze di 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

Importante

Le voci uguali in un elenco chiamate includono tutti i parametri fissi nella chiamata, incluso il ricevitore. Il ricevitore è l'istanza di un oggetto rappresentato da this quando viene richiamata la voce.

var o1 = new object();
var o2 = new object();
var d1 = o1.ToString;
var d2 = o2.ToString;
Console.WriteLine(object.ReferenceEquals(d1, d2));  // output: False
Console.WriteLine(d1 == d2);  // output: False (different receivers)

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