Base Equals Reference
ID |
csharp.base_equals_reference |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
CSharp |
Tags |
equals, reliability |
Description
Reports Equals(object obj) overrides whose body simply returns base.Equals(obj). On a
non-record class this delegates to System.Object.Equals, which is reference identity,
so the override adds nothing — and any caller that expected structural equality gets
broken behaviour.
Rationale
If you override Equals you almost always want structural equality (compare fields).
base.Equals(obj) on object is reference identity, which means the override returns
true only when both arguments are the very same instance. Records are exempt because
the compiler-generated structural Equals lives on the record type itself, so
delegating to it from a record’s explicit override is legitimate.
public class Money
{
public decimal Amount { get; }
public override bool Equals(object obj)
{
return base.Equals(obj); // FLAW — reference identity
}
}
public class MoneyOk
{
public decimal Amount { get; }
public override bool Equals(object obj)
{
return obj is MoneyOk m && m.Amount == Amount; // OK
}
public override int GetHashCode() => Amount.GetHashCode();
}