Equals Signature Correct
ID |
csharp.equals_signature_correct |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
CSharp |
Tags |
CWE:581, equals, reliability |
Description
Reports Equals methods whose signature deviates from the canonical
public override bool Equals(object obj). The rule flags overrides whose parameter
type is not object (which do not actually override System.Object.Equals) and
instance Equals methods whose return type is not bool.
Rationale
C# resolves overrides by exact parameter type, so public override bool Equals(MyType other)
silently fails to override object.Equals(object). Hash-based collections still call the
base reference-identity comparison, and the developer’s intended equality logic is bypassed.
Likewise, an Equals method that returns anything other than bool cannot participate in
the IEquatable<T> or object.Equals contract.
public class Money
{
public override bool Equals(Money other) // FLAW — wrong parameter type
=> other != null && other.Amount == Amount;
public int Equals(object obj) // FLAW — wrong return type
=> obj is Money m && m.Amount == Amount ? 1 : 0;
}
public class MoneyOk
{
public override bool Equals(object obj) // OK
=> obj is MoneyOk m && m.Amount == Amount;
}
Remediation
Use the canonical signature public override bool Equals(object obj) when overriding
System.Object.Equals. If you also want a strongly-typed comparison, implement
IEquatable<T> and add a separate bool Equals(T other) method that the override
delegates to. Always pair the override with GetHashCode.