Code Inspection: Possible unintended reference comparison
C# compiler issues the 'Possible unintended reference comparison' warnings
(CS0252/
CS0253)
in cases where you use equality operators (==
or
!=
) on objects of types that inherit from one another and only one of the types overrides
these operators.
The fact that the equality operators are overridden in one of the types means that
value equality is expected when objects of this type are compared.
Comparing these objects with objects of types where the equality operators are not overridden will lead
to using the overload from
System.Object
, which checks
reference equality.
So a warning is issued because comparing object references is most likely erroneous in this situation.
Although ReSharper knows about these warnings and provides
design-time notifications for them, it goes one step further
and detects another case of possible unintended reference comparison - when only one of the compared types
overrides
Equals()
.
MSDN documentation says:
Any class that represents a value, essentially any value type,
or a set of values as a group, such as a complex number class, should override Equals.
So if
Equals()
is not overridden for the second object's type, then the comparison falls back to
the implementation of
Equals()
in
System.Object
, which performs a reference identity check,
which is most probably not desired for a value type.
Here is a code listing that illustrates both situations:
class MyType
{
}
class TypeWithEquals : MyType
{
public override bool Equals(object obj)
{
throw new NotImplementedException();
}
}
class TypeWithEqOperators : MyType
{
public static bool operator ==(TypeWithEqOperators left, TypeWithEqOperators right)
{
throw new NotImplementedException();
}
public static bool operator !=(TypeWithEqOperators left, TypeWithEqOperators right)
{
throw new NotImplementedException();
}
}
class Test
{
public Test(TypeWithEquals withEquals, TypeWithEqOperators withEqOperators, MyType parentObject)
{
bool a = withEqOperators == parentObject; // CS0253
bool b = withEquals == parentObject; // No compiler warnings, but ReSharper issues its own warning here
}
}