IComparable implemented without comparison operators

ID

vbnet.correctness.icomparable_needs_operators

Severity

low

Remediation Complexity

medium

Remediation Risk

low

Remediation Effort

low

Resource

Type Design

Language

VB.NET

Description

Reports a type that implements IComparable or IComparable(Of T) but declares none of the comparison operators <, >, and >=. A comparable type that declares at least one of them is not reported, and neither is a type that only overloads = and <>, which express equality rather than ordering.

Rationale

Implementing IComparable states that instances of the type have a well-defined order, and CompareTo is what sorting, SortedList, SortedSet and LINQ’s OrderBy will call. Callers writing ordinary code, however, reach for a < b. Without the operators that expression does not compile, so every comparison at a call site has to be spelled a.CompareTo(b) < 0 - easy to get backwards, and easy to write inconsistently across a codebase. Worse, when the operators are added later by someone unaware of CompareTo, the two can disagree: a < b and a.CompareTo(b) < 0 then give different answers for the same pair, and which one runs depends on whether the call site is generic or concrete.

The following code illustrates the pattern detected by this rule:

Namespace Acme.Catalog

    ' FLAGGED: IComparable implemented without comparison operators
    Public Structure PartNumber
        Implements IComparable

        Public Sequence As Integer

        Public Function CompareTo(ByVal obj As Object) As Integer Implements IComparable.CompareTo
            Return Sequence.CompareTo(DirectCast(obj, PartNumber).Sequence)
        End Function

Remediation

Implement CompareTo once as the single definition of the order, then add Public Shared Operator <, >, and >= as one-line delegations to it, for example Return a.CompareTo(b) < 0. Add the = and <> operators together with an Equals override in the same pass, so that equality and ordering agree on the boundary case where CompareTo returns zero.

Configuration

This detector does not need any configuration.