Possible Unintended Reference Compare

ID

csharp.possible_unintended_ref_compare

Severity

low

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

CSharp

Tags

equality, reliability

Description

Reports == or != comparisons between two operands whose types resolve to a class declared in the same compilation unit that does not overload operator ==. In such a case the operator falls back to reference identity, which is rarely the intent.

Rationale

C# uses reference identity for the default == between objects. When the developer genuinely wants structural equality (compare field values), the type needs to overload operator == (and Equals/GetHashCode). Without that overload, comparing two instances with == returns true only when they are the very same allocation, which makes the comparison silently wrong for value-like types.

public class Money
{
    public decimal Amount { get; set; }
}

public class Wallet
{
    public bool Same(Money a, Money b)
    {
        return a == b;                                          // FLAW - reference equality
    }
}

public class MoneyOk
{
    public decimal Amount { get; set; }

    public static bool operator ==(MoneyOk a, MoneyOk b) =>
        a is null ? b is null : a.Amount == b.Amount;

    public static bool operator !=(MoneyOk a, MoneyOk b) => !(a == b);

    public override bool Equals(object obj) => obj is MoneyOk m && m.Amount == Amount;
    public override int GetHashCode() => Amount.GetHashCode();
}

public class WalletOk
{
    public bool Same(MoneyOk a, MoneyOk b)
    {
        return a == b;                                          // OK - operator overload exists
    }

    public bool NullCheck(Money a) => a == null;                // OK - null compare allowed
}

Remediation

Either overload operator == (and !=, Equals, GetHashCode) on the class so the comparison expresses structural equality, or call Equals(a, b) / object.Equals(a, b) explicitly. For records, the compiler does both automatically.

References