Операторы равенства — проверка того, равны ли два объекта или нет
Операторы ==
(равенство) и !=
(неравенство) проверяют равенство или неравенство своих операндов. Типы значений равны, если их содержимое равно. Ссылочные типы равны, если две переменные ссылаются на одно хранилище.
Оператор равенства ==
Оператор равенства ==
возвращает значение true
, если его операнды равны. В противном случае возвращается значение false
.
Равенство типов значений
Операнды встроенных типов значений равны, если равны их значения.
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
Примечание.
У операторов ==
, <
, >
, <=
и >=
, если какой-то из операндов не является числом (Double.NaN или Single.NaN), результатом операции является false
. Это означает, что значение NaN
не больше, не меньше и не равно любому другому значению double
(или float
), включая NaN
. Дополнительные сведения и примеры см. в справочных статьях по Double.NaN или Single.NaN.
Два операнда одного типа enum равны, если равны соответствующие значения базового целочисленного типа.
По умолчанию пользовательские типы struct не поддерживают оператор ==
. Чтобы поддерживать оператор ==
, пользовательская структура должна перегружать его.
Кортежи ==
C# поддерживаются операторами!=
. Дополнительные сведения см. в разделе Равенство кортежей статьи Типы кортежей.
Равенство ссылочных типов
По умолчанию два операнда ссылочного типа, отличные от записи, являются равными, если они ссылаются на один и тот же объект.
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
}
}
Как показано в примере, определяемые пользователем ссылочные типы поддерживают оператор ==
по умолчанию. Однако ссылочный тип может перегружать оператор ==
. Если ссылочный тип перегружает оператор ==
, воспользуйтесь методом Object.ReferenceEquals, чтобы проверить, что две ссылки этого типа указывают на один и тот же объект.
Равенство типов записей
Типы записей поддерживают ==
операторы !=
, которые по умолчанию предоставляют семантику равенства значений. То есть два операнда записей равны, если оба из них являются null
или соответствующими значениями всех полей и автоматически реализованы свойства равны.
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
}
}
Как показано в предыдущем примере, для элементов ссылочного типа, не относящихся к записи, сравниваются их ссылочные значения, а не для ссылочных экземпляров.
Равенство строк
Два операнда string равны, если они оба имеют значение null
или оба экземпляра строки имеют одинаковую длину и идентичные символы в каждой позиции символа.
string s1 = "hello!";
string s2 = "HeLLo!";
Console.WriteLine(s1 == s2.ToLower()); // output: True
string s3 = "Hello!";
Console.WriteLine(s1 == s3); // output: False
Сравнение равенства строк — это порядковые сравнения с учетом регистра. Дополнительные сведения о том, как сравнивать строки, см. в статье Сравнение строк в C#.
Равенство делегатов
Два операнда делегатов одного типа среды выполнения равны, если оба из них имеют значение null
или их списки вызовов имеют одинаковую длину и содержат одинаковые записи в каждой позиции:
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
Подробные сведения см. в разделе Delegate equality operators (Операторы равенства делегатов) в спецификации языка C#.
Делегаты, созданные из оценки семантических лямбда-выражений , не равны, как показано в следующем примере:
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
Оператор неравенства !=
Оператор неравенства !=
возвращается true
, если его операнды не равны, false
в противном случае. Для операндов встроенных типов выражение x != y
дает тот же результат, что и выражение !(x == y)
. Дополнительные сведения о равенстве типов см. в разделе Оператор равенства.
В следующем примере иллюстрируется использование оператора !=
.
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
Возможность перегрузки оператора
Определяемый пользователем тип может перегружать операторы ==
и !=
. Если тип перегружает один из двух операторов, он должен также перегружать и другой.
Тип записи не может явно перегружать ==
операторы и !=
операторы. Если необходимо изменить поведение операторов ==
и !=
для типа записи T
, реализуйте метод IEquatable<T>.Equals со следующей сигнатурой.
public virtual bool Equals(T? other);
Спецификация языка C#
Дополнительные сведения см. в разделе Операторы отношения и проверки типа в статье по спецификации языка C#.
Дополнительные сведения о равенстве типов записей см. в разделе Элементы равенства предложения функции записей.