Operadores de igualdade - testam se dois objetos são iguais ou não

Os operadores == (igualdade) e != (desigualdade) verificam se os operandos são iguais ou não. Os tipos de valor são iguais quando seu conteúdo é igual. Os tipos de referência são iguais quando as duas variáveis se referem ao mesmo armazenamento.

Operador de igualdade ==

O operador de igualdade == retornará true se seus operandos forem iguais; caso contrário, false.

Igualdade de tipos de valor

Os operandos dos tipos de valor internos serão iguais se seus valores forem iguais:

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

Observação

Para os operadores ==, <, >, <= e >=, se nenhum dos operandos for um número (Double.NaN ou Single.NaN), o resultado da operação será false. Isso significa que o valor NaN não é superior, inferior nem igual a nenhum outro valor double (ou float), incluindo NaN. Para obter mais informações e exemplos, consulte o artigo de referência Double.NaN ou Single.NaN.

Dois operandos do mesmo tipo de enum serão iguais se os valores correspondentes do tipo integral subjacente forem iguais.

Os tipos struct definidos pelo usuário não dão suporte ao operador ==, por padrão. Para dar suporte ao operador ==, um struct definido pelo usuário precisa sobrecarregá-lo.

Os operadores == e != são compatíveis com as C# tuplas. Para obter mais informações, consulte a seção Igualdade de tupla do artigo Tipos de tupla.

Igualdade de tipos de referência

Por padrão, dois operandos do tipo de referência não registrados são iguais quando se referem ao mesmo objeto:

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
    }
}

Como mostra o exemplo, os tipos de referência definidos pelo usuário dão suporte ao operador ==, por padrão. No entanto, um tipo de referência pode sobrecarregar o operador ==. Se um tipo de referência sobrecarregar o operador ==, use o método Object.ReferenceEquals para verificar se as duas referências desse tipo dizem respeito ao mesmo objeto.

Igualdade de tipos de registro

Os tipos de registro dão suporte aos operadores == e != que, por padrão, fornecem semântica de igualdade de valor. Ou seja, dois operandos de registro são iguais quando ambos são null ou os valores correspondentes de todos os campos e propriedades implementadas automaticamente são iguais.

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
    }
}

Como mostra o exemplo anterior, para membros do tipo de referência não registrados, seus valores de referência é que são comparados, e não as instâncias referenciadas.

Igualdade da cadeia de caracteres

Dois operandos da cadeia de caracteres serão iguais quando ambos forem null ou ambas as instâncias da cadeia de caracteres tiverem o mesmo comprimento e caracteres idênticos em cada posição de caractere:

string s1 = "hello!";
string s2 = "HeLLo!";
Console.WriteLine(s1 == s2.ToLower());  // output: True

string s3 = "Hello!";
Console.WriteLine(s1 == s3);  // output: False

Comparações de igualdade de cadeia de caracteres são comparações ordinais que diferenciam maiúsculas de minúsculas. Para obter mais informações sobre a comparação de cadeias de caracteres, confira Como comparar cadeias de caracteres no C#.

Igualdade de delegado

Os dois operandos delegate do mesmo tipo de tempo de execução são iguais quando ambos são null ou suas listas de invocação são do mesmo comprimento e tem entradas iguais em cada posição:

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

Saiba mais na seção Operadores de igualdade de delegados na Especificação da linguagem C#.

Os delegados produzidos pela avaliação de expressões lambda semanticamente idênticas não são iguais, como mostra o exemplo a seguir:

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

Operador de desigualdade !=

O operador de desigualdade != retornará true se os seus operandos não forem iguais; caso contrário, false. No caso dos operandos de tipos internos, a expressão x != y gera o mesmo resultado que a expressão !(x == y). Para obter mais informações sobre a igualdade de tipos, confira a seção Operador de igualdade.

O exemplo a seguir demonstra o uso do operador !=:

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

Capacidade de sobrecarga do operador

Os tipos definidos pelo usuário podem sobrecarregar os operadores == e !=. Se um tipo sobrecarregar um dos dois operadores, ele também precisará sobrecarregar o outro.

Um tipo de registro não pode sobrecarregar explicitamente os operadores == e !=. Se você precisar alterar o comportamento dos operadores == e != para o tipo de registro T, implemente o método IEquatable<T>.Equals com a seguinte assinatura:

public virtual bool Equals(T? other);

Especificação da linguagem C#

Para obter mais informações, consulte a seção Operadores de teste de tipo e relacional na Especificação da linguagem C#.

Para obter mais informações sobre a igualdade de tipos de registro, consulte a seção Membros de igualdade da nota de proposta de recurso de registros.

Confira também