Operatory równości — testowanie, czy dwa obiekty są równe, czy nie
Operatory ==
(równości) i!=
(nierówności) sprawdzają, czy ich operandy są równe, czy nie. Typy wartości są równe, gdy ich zawartość jest równa. Typy referencyjne są równe, gdy dwie zmienne odwołują się do tego samego magazynu.
Operator równości ==
Operator ==
równości zwraca true
wartość , jeśli jego operandy są równe, false
w przeciwnym razie.
Równość typów wartości
Operandy wbudowanych typów wartości są równe, jeśli ich wartości są równe:
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
Uwaga
==
W przypadku operatorów , ,<
>
, <=
i>=
, jeśli którykolwiek z operandów nie jest liczbą (Double.NaN lub Single.NaN), wynikiem operacji jest .false
Oznacza to, że NaN
wartość nie jest ani większa niż, mniejsza ani równa żadnej innej double
wartości (lub float
), w tym NaN
. Aby uzyskać więcej informacji i przykładów, zobacz Double.NaN artykuł lub reference (Dokumentacja Single.NaN ).
Dwa operandy tego samego typu wyliczenia są równe, jeśli odpowiadające im wartości bazowego typu całkowitego są równe.
Typy struktur zdefiniowanych przez użytkownika nie obsługują ==
operatora domyślnie. Aby obsługiwać ==
operator, struktura zdefiniowana przez użytkownika musi ją przeciążyć.
Operatory ==
i !=
są obsługiwane przez krotki języka C#. Aby uzyskać więcej informacji, zobacz sekcję Równości krotki w artykule Typy krotki.
Równość typów odwołań
Domyślnie dwa operandy inne niż rekordy typu odwołania są równe, jeśli odwołują się do tego samego obiektu:
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
}
}
Jak pokazano w przykładzie, typy referencyjne zdefiniowane przez użytkownika obsługują ==
operator domyślnie. Jednak typ odwołania może przeciążyć ==
operatora. Jeśli typ odwołania przeciąża ==
operatora, użyj Object.ReferenceEquals metody , aby sprawdzić, czy dwa odwołania tego typu odwołują się do tego samego obiektu.
Równość typów rekordów
Typy rekordów obsługują ==
operatory i !=
, które domyślnie zapewniają semantyka równości wartości. Oznacza to, że dwa operandy rekordów są równe, gdy oba z nich są null
lub odpowiadające wartości wszystkich pól i automatycznie zaimplementowane właściwości są równe.
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
}
}
Jak pokazano w poprzednim przykładzie, w przypadku składowych niebędących rekordami typu odwołania są porównywane ich wartości referencyjne, a nie wystąpienia, do których odwołuje się odwołanie.
Równość ciągów
Dwa operandy ciągów są równe, gdy oba z nich są null
lub oba wystąpienia ciągów mają taką samą długość i mają identyczne znaki w każdej pozycji znaku:
string s1 = "hello!";
string s2 = "HeLLo!";
Console.WriteLine(s1 == s2.ToLower()); // output: True
string s3 = "Hello!";
Console.WriteLine(s1 == s3); // output: False
Porównania równości ciągów to porównania porządkowe z uwzględnieniem wielkości liter. Aby uzyskać więcej informacji na temat porównywania ciągów, zobacz Jak porównać ciągi w języku C#.
Deleguj równość
Dwa operandy delegatów tego samego typu czasu wykonywania są równe, gdy oba z nich są null
lub ich listy wywołań mają taką samą długość i mają równe wpisy w każdej pozycji:
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
Aby uzyskać więcej informacji, zobacz sekcję Delegowanie operatorów równości specyfikacji języka C#.
Delegaty generowane na podstawie oceny identycznych wyrażeń lambda semantycznie nie są równe, jak pokazano w poniższym przykładzie:
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
Operator nierówności !=
Operator !=
nierówności zwraca wartość true
, jeśli jego operandy nie są równe, false
w przeciwnym razie. W przypadku operandów wbudowanych typów wyrażenie generuje ten sam wynik co wyrażenie x != y
!(x == y)
. Aby uzyskać więcej informacji na temat równości typów, zobacz sekcję Operator równości .
W poniższym przykładzie pokazano użycie !=
operatora:
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
Przeciążenie operatora
Typ zdefiniowany przez użytkownika może przeciążać ==
operatory i!=
. Jeśli typ przeciąża jeden z dwóch operatorów, musi również przeciążyć drugi.
Typ rekordu ==
nie może jawnie przeciążać operatorów i !=
. Jeśli musisz zmienić zachowanie operatorów ==
i !=
dla typu T
rekordu , zaimplementuj metodę IEquatable<T>.Equals przy użyciu następującego podpisu:
public virtual bool Equals(T? other);
specyfikacja języka C#
Aby uzyskać więcej informacji, zobacz sekcję Operatory relacyjne i testowe typów specyfikacji języka C#.
Aby uzyskać więcej informacji na temat równości typów rekordów, zobacz sekcję Elementy członkowskie równości w notatce propozycji funkcji rekordów.