Ответ
Метод Equals, унаследованный от базового класса System.Object, принимает один параметр типа object. Это позволяет сравнивать текущий экземпляр с любым другим объектом.
Сигнатура:
public virtual bool Equals(object? obj)
Пример переопределения в пользовательском классе:
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public override bool Equals(object obj)
{
// 1. Проверка на null и совпадение типов
if (obj == null || GetType() != obj.GetType())
return false;
// 2. Приведение типа и сравнение значимых полей
Product other = (Product)obj;
return Id == other.Id && Name == other.Name;
}
// Переопределение GetHashCode обязательно при переопределении Equals
public override int GetHashCode() => HashCode.Combine(Id, Name);
}
Проблема и улучшение: Поскольку параметр — object, необходимы проверки типа и приведение, что снижает производительность из-за упаковки (для структур) и динамических проверок. Для решения этой проблемы в .NET введён интерфейс IEquatable<T>.
Рекомендация: Всегда реализуйте IEquatable<T> вместе с переопределением Object.Equals для типов-значений (struct) и часто сравниваемых ссылочных типов (class). Метод IEquatable<T>.Equals принимает типизированный параметр (T), что делает сравнение безопасным и эффективным.