ReSharper 2016.3 Help

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 } }
Last modified: 12 October 2017

See Also