Проверка равенства (руководство по программированию на C#)

Иногда возникает необходимость проверить равенство двух значений. В некоторых случаях проверяется равенство значений, которое также называют их эквивалентностью, что означает, что содержащиеся в двух переменных значения равны. В других случаях требуется определить, ссылаются ли две переменные на один и тот же объект в памяти. Такой тип равенства называется равенством ссылок или идентичностью. В этом разделе описаны эти два типа равенства и приведены ссылки на разделы, содержащие дополнительные сведения.

Равенство ссылок

Равенство ссылок означает, что два объекта ссылаются на один и тот же объект. Это может произойти при простом присваивании, как показано в следующем примере.

using System;
class Test
{
    public int Num { get; set; }
    public string Str { get; set; }

    public static void Main()
    {
        Test a = new Test() { Num = 1, Str = "Hi" };
        Test b = new Test() { Num = 1, Str = "Hi" };

        bool areEqual = System.Object.ReferenceEquals(a, b);
        // False:
        System.Console.WriteLine("ReferenceEquals(a, b) = {0}", areEqual);

        // Assign b to a.
        b = a;

        // Repeat calls with different results.
        areEqual = System.Object.ReferenceEquals(a, b);
        // True:
        System.Console.WriteLine("ReferenceEquals(a, b) = {0}", areEqual);
    }
}

В этом фрагменте кода создается два объекта, но после инструкции присваивания они оба ссылаются на один и тот же объект. Поэтому между ними устанавливается равенство ссылок. Метод ReferenceEquals позволяет определить, ссылаются ли две ссылки на один и тот же объект.

Концепция равенства ссылок применима только к ссылочным типам. Объекты типа значения не могут иметь равенство ссылок, поскольку переменной присваивается экземпляр типа значения, создается копия этого значения. Поэтому две распакованные структуры никогда не могут ссылаться на одно и то же расположение в памяти. Более того, для сравнения двух типов значений ReferenceEquals всегда будет возвращаться результат false, даже если содержащиеся в объектах значения идентичны. Это связано с тем, что каждая переменная запакована в отдельный экземпляр объекта. См. сведения в руководстве по тестированию на равенство (идентичность) ссылок.

Равенство значений

Равенство значений означает, что два объекта содержат одинаковое значение или одинаковые значения. Для примитивных типов значений, таких как int или bool, проверка на равенство значений представляет собой очевидную задачу. Можно использовать оператор ==, как показано в следующем примере.

int a = GetOriginalValue();  
int b = GetCurrentValue();  
  
// Test for value equality.
if (b == a)
{  
    // The two integers are equal.  
}  

Для большинства других типов проверка равенства значений является более сложной, поскольку при этом необходимо понимать, как равенство определено в типе. Для всех классов и структур, имеющих несколько полей или свойств, равенство значений часто определяется как равенство значений всех полей и свойств. Например, два объекта Point могут быть определены как равные, если значение pointA.X равняется pointB.X, а значение pointA.Y равняется pointB.Y. Для записей равенство значений означает, что две переменные типа "запись" равны, если совпадают типы и все значения свойств и полей.

Однако общего требования о том, что равенство должно определяться на основе всех полей в типе, нет. Оно может определяться и на основе части полей. При сравнении значений типов сторонних разработчиков необходимо понимать, как именно реализовано равенство для таких типов. См. сведения об определении равенства значений в собственных классах и структурах в руководстве по определению равенства значений для типа.

Равенство значений с плавающей запятой

Проверка равенства значений с плавающей запятой (double и float) представляет проблему из-за неточности арифметических операций с плавающей запятой на двоичных компьютерах. Дополнительные сведения можно найти в заметках в разделе System.Double.

Заголовок Description
Проверка на равенство ссылок (идентичность) Описание процедуры проверки равенства ссылок двух переменных.
Определение равенства значений для типа Описание предоставления пользовательского определения равенства значений для типа.
Типы Сведения о системе типов C# и ссылки на дополнительные сведения.
Записи Предоставляет сведения о типах записей, которые по умолчанию проверяют равенство значений.