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.

Il riferimento al linguaggio C# documenta la versione rilasciata più di recente del linguaggio C#. Contiene anche la documentazione iniziale per le funzionalità nelle versioni di anteprima pubblica per la prossima versione del linguaggio di programmazione.

La documentazione identifica tutte le funzionalità introdotte nelle ultime tre versioni della lingua o nelle anteprime pubbliche correnti.

Suggerimento

Per trovare quando una funzionalità è stata introdotta per la prima volta in C#, vedere l'articolo sulla cronologia delle versioni del linguaggio C#.

È 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. Questa condizione indica che il NaN valore non è maggiore, 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 hanno 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 provenienti dalla valutazione di espressioni lambda semanticamente identiche non sono uguali, come illustrato nell'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 non sono uguali e 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 come usare l'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

È possibile eseguire l'overload degli == operatori e != in un tipo definito dall'utente. Se si esegue l'overload di uno di questi due operatori, è necessario eseguire anche l'overload dell'altro operatore.

Non è possibile eseguire in modo esplicito l'overload degli == operatori e != in un tipo di record. Per modificare il comportamento degli == operatori e != per il tipo di Trecord , implementare il IEquatable<T>.Equals metodo 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