V3192. Type member is used in the 'GetHashCode' method but is missing from the 'Equals' method.
Анализатор обнаружил возможную ошибку, связанную с тем, что один из членов класса не используется в методе '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;
}
Данная диагностика классифицируется как: