V3192. Type member is used in the 'GetHashCode' method but is missing from the 'Equals' method.
The analyzer has detected a possible error: a class member is missing from the 'Equals' method but is used in the 'GetHashCode' method.
Look at the following code:
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();
}
}
In this example, the 'controlUrl' field is missing from the 'Equals' method but is used in 'GetHashCode'. There can be two reasons:
- The developers may have forgotten about the comparison of 'controlUrl' in the 'Equal' method.
- The developers decided not to use the 'controlUrl' field in the 'Equals' method.
Both reasons lead to the same problem — the 'GetHashCode' method can return different values for two equivalent objects. According to the Microsoft documentation, the 'GetHashCode' method should return equal hash codes for any two equal objects. So, call to 'Equals' returns 'True' for these objects.
In this case, the 'Equals' method returns 'True' for two objects with equal 'hostEndPoint' and 'serviceDescriptionUrl' fields. The result of 'GetHashCode' also depends on 'controlUrl'. This can indicate an error. Also, this implementation may negatively affect the correct work with the collections: 'Hashtable', 'Dictionary<TKey,TValue>', etc.
The fixed version:
public override bool Equals(object obj)
{
if (obj is UpnpNatDevice other)
{
return hostEndPoint.Equals(other.hostEndPoint)
&& serviceDescriptionUrl == other.serviceDescriptionUrl
&& controlUrl == other.controlUrl;
}
return false;
}
This diagnostic is classified as: