Unicorn with delicious cookie
Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо
to the top
>
>
>
V3192. Type member is used in the...
menu mobile close menu
Проверка проектов
Дополнительная информация
toggle menu Оглавление

V3192. Type member is used in the 'GetHashCode' method but is missing from the 'Equals' method.

15 Сен 2023

Анализатор обнаружил возможную ошибку, связанную с тем, что один из членов класса не используется в методе 'Equals' и при этом используется в методе 'GetHashCode'.

Рассмотрим пример:

public class UpnpNatDevice
{
  private EndPoint hostEndPoint;
  private string serviceDescriptionUrl;
  private string controlUrl;

  public override bool Equals(object obj)
  {
    if (obj is UpnpNatDevice other)
    {
      return    hostEndPoint.Equals(other.hostEndPoint)
             && serviceDescriptionUrl == other.serviceDescriptionUrl;
    }

    return false;
  }

  public override int GetHashCode()
  {
    return   hostEndPoint.GetHashCode()
           ^ controlUrl.GetHashCode()
           ^ serviceDescriptionUrl.GetHashCode();
  }
}

В данном примере поле 'controlUrl' не используется в методе 'Equals', но при этом присутствует в 'GetHashCode'. Это возможно в двух ситуациях:

  • в методе 'Equals' забыли сравнить поле 'controlUrl';
  • разработчики решили не использовать поле 'controlUrl' в методе 'Equals'.

Обе ситуации приводят к одной проблеме – метод 'GetHashCode' может возвращать разные значения для двух эквивалентных объектов. Исходя из документации Microsoft, метод 'GetHashCode' должен возвращать одинаковый хэш код для любых двух объектов, для которых вызов 'Equals' возвращает 'True'.

В данном случае для двух объектов с одинаковыми полями 'hostEndPoint' и 'serviceDescriptionUrl' метод 'Equals' вернёт 'True'. При этом результат 'GetHashCode' зависит ещё и от 'controlUrl'. Это может свидетельствовать об ошибке. Также подобная реализация может негативно сказаться на корректности работы с коллекциями 'Hashtable', 'Dictionary<TKey,TValue>' и другими.

Исправленный вариант:

public override bool Equals(object obj)
{
  if (obj is UpnpNatDevice other)
  {
    return    hostEndPoint.Equals(other.hostEndPoint)
           && serviceDescriptionUrl == other.serviceDescriptionUrl
           && controlUrl == other.controlUrl;
  }

  return false;
}

Данная диагностика классифицируется как:

Взгляните на примеры ошибок, обнаруженных с помощью диагностики V3192.