
Inline adoc files when they are included exactly once. Also fix language tags because this inlining gives us better information on what language the code is written in.
93 lines
2.5 KiB
Plaintext
93 lines
2.5 KiB
Plaintext
== Why is this an issue?
|
|
|
|
Using the equality ``++==++`` and inequality ``++!=++`` operators to compare two objects generally works. The operators can be overloaded, and therefore the comparison can resolve to the appropriate method. However, when the operators are used on interface instances, then ``++==++`` resolves to reference equality, which may result in unexpected behavior if implementing classes override ``++Equals++``. Similarly, when a class overrides ``++Equals++``, but instances are compared with non-overloaded ``++==++``, there is a high chance that value comparison was meant instead of the reference one.
|
|
|
|
=== Noncompliant code example
|
|
|
|
[source,csharp]
|
|
----
|
|
public interface IMyInterface
|
|
{
|
|
}
|
|
|
|
public class MyClass : IMyInterface
|
|
{
|
|
public override bool Equals(object obj)
|
|
{
|
|
//...
|
|
}
|
|
}
|
|
|
|
public class Program
|
|
{
|
|
public static void Method(IMyInterface instance1, IMyInterface instance2)
|
|
{
|
|
if (instance1 == instance2) // Noncompliant, will do reference equality check, but was that intended? MyClass overrides Equals.
|
|
{
|
|
Console.WriteLine("Equal");
|
|
}
|
|
}
|
|
}
|
|
----
|
|
|
|
=== Compliant solution
|
|
|
|
[source,csharp]
|
|
----
|
|
public interface IMyInterface
|
|
{
|
|
}
|
|
|
|
public class MyClass : IMyInterface
|
|
{
|
|
public override bool Equals(object obj)
|
|
{
|
|
//...
|
|
}
|
|
}
|
|
|
|
public class Program
|
|
{
|
|
public static void Method(IMyInterface instance1, IMyInterface instance2)
|
|
{
|
|
if (object.Equals(instance1, instance2)) // object.Equals checks for null and then calls the instance based Equals, so MyClass.Equals
|
|
{
|
|
Console.WriteLine("Equal");
|
|
}
|
|
}
|
|
}
|
|
----
|
|
|
|
=== Exceptions
|
|
|
|
The rule does not report on comparisons of ``++System.Type++`` instances and on comparisons inside ``++Equals++`` overrides.
|
|
|
|
It also does not raise an issue when one of the operands is ``++null++`` nor when one of the operand is cast to ``++object++`` (because in this case we want to ensure reference equality even if some ``++==++`` overload is present).
|
|
|
|
include::../see.adoc[]
|
|
|
|
ifdef::env-github,rspecator-view[]
|
|
|
|
'''
|
|
== Implementation Specification
|
|
(visible only on this page)
|
|
|
|
=== Message
|
|
|
|
Consider using "Equals" if value comparison was intended.
|
|
|
|
|
|
'''
|
|
== Comments And Links
|
|
(visible only on this page)
|
|
|
|
=== on 8 Dec 2015, 14:07:51 Tamas Vajk wrote:
|
|
\[~ann.campbell.2] Could you check this subtask. It's a relatively big change from the parent task.
|
|
|
|
=== on 8 Dec 2015, 16:35:02 Ann Campbell wrote:
|
|
looks fine [~tamas.vajk]
|
|
|
|
include::../comments-and-links.adoc[]
|
|
|
|
endif::env-github,rspecator-view[]
|