Как реализовать сравнение объектов в C#?

Пользователь

от enid , в категории: Другие , год назад

Как реализовать сравнение объектов в C#?

Facebook Vk Ok Twitter LinkedIn Telegram Whatsapp

2 ответа

Пользователь

от cayla , год назад

@enid 

Для реализации сравнения объектов в C# необходимо переопределить методы Equals() и GetHashCode().

  1. Переопределение метода Equals(): Метод Equals() является виртуальным методом класса Object, который получает в качестве параметра объект типа Object и возвращает значение bool, указывающее равны ли два объекта. В переопределении метода Equals() необходимо сначала проверить, является ли переданный объект null. Если объект null, то сравнение не имеет смысла и метод должен вернуть false. Затем нужно проверить, является ли переданный объект того же типа, что и текущий объект, для этого можно воспользоваться оператором is. Если типы объектов не совпадают, метод должен вернуть false. В дополнение к проверке типов, можно добавить сравнение значений полей объектов, если они являются значимыми типами, или использовать рекурсивный вызов метода Equals(), если они являются ссылочными типами. Если все проверки пройдены успешно, можно считать, что объекты равны и метод должен вернуть true.
  2. Переопределение метода GetHashCode(): Метод GetHashCode() также является виртуальным методом класса Object и возвращает хэш-код объекта, который используется в структурах данных, основанных на хэш-таблицах, таких как Dictionary или HashSet. Хэш-код должен быть рассчитан таким образом, чтобы объекты с равными значениями полей имели одинаковый хэш-код. Чтобы переопределить метод GetHashCode(), необходимо выбрать некоторое число, которое будет использоваться для смешивания хэш-кодов полей объекта, например, с использованием операции побитового исключающего ИЛИ (XOR). Для каждого поля объекта, которое участвует в сравнении, необходимо добавить его хэш-код в рассчитываемый хэш-код объекта. В конце, рассчитанный хэш-код должен быть возвращен методом.


Пример реализации сравнения объектов в C#:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }

    public override bool Equals(object obj)
    {
        if (obj == null)
            return false;

        if (!(obj is Person))
            return false;

        Person otherPerson = (Person)obj;
        return this.Name == otherPerson.Name && this.Age == otherPerson.Age;
    }

    public override int GetHashCode()
    {
        int hash = 17;
        hash = hash * 23 + Name.GetHashCode();
        hash = hash * 23 + Age.GetHashCode();
        return hash;
    }
}


Теперь объекты класса Person можно сравнивать с помощью оператора == или метода Equals():

1
2
3
4
Person person1 = new Person { Name = "John", Age = 30 };
Person person2 = new Person { Name = "John", Age = 30 };
Console.WriteLine(person1 == person2); // Output: False
Console.WriteLine(person1.Equals(person2)); // Output: True


Пользователь

от jerad.kuphal , 6 месяцев назад

@enid 

Верно, для корректного сравнения объектов в C# важно переопределить методы Equals() и GetHashCode() на уровне элементарных типов данных объекта. Ваш пример демонстрирует как это можно сделать для класса Person.


Дополнительно, при реализации собственных классов, можно также переопределить операторы == и != для удобства сравнения объектов, что позволит использовать их в коде более естественным образом.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
public static bool operator ==(Person person1, Person person2)
{
    if (ReferenceEquals(person1, person2))
        return true;

    if (person1 is null || person2 is null)
        return false;

    return person1.Equals(person2);
}

public static bool operator !=(Person person1, Person person2)
{
    return !(person1 == person2);
}


Теперь можно использовать операторы == и != для сравнения объектов класса Person:

1
2
3
4
Person person1 = new Person { Name = "John", Age = 30 };
Person person2 = new Person { Name = "John", Age = 30 };
Console.WriteLine(person1 == person2); // Output: True
Console.WriteLine(person1 != person2); // Output: False


Данный подход позволит эффективно сравнивать объекты и использовать их в различных структурах данных, таких как HashSet или в качестве ключей в словарях.