Use Ordinal String Comparison

ID

csharp.use_ordinal_string_comparison

Severity

low

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

CSharp

Tags

culture, performance, reliability

Description

Reports String.Equals(other, StringComparison.CurrentCulture[IgnoreCase]) and the InvariantCulture[IgnoreCase] variants. Culture-aware string equality is 10-100x slower than the ordinal comparators because it walks the locale collation tables.

Rationale

For invariant data — protocol tokens, identifiers, file paths, JSON keys — the locale should not influence the comparison. The ordinal comparators (Ordinal / OrdinalIgnoreCase) compare code-point by code-point, are deterministic across runtimes, and are dramatically faster. Reserve the culture-aware comparators for text the user actually sees in their language.

public class Compare
{
    public bool MatchCurrent(string a, string b)
    {
        return a.Equals(b, StringComparison.CurrentCulture);                 // FLAW
    }

    public bool MatchInvariantI(string a, string b)
    {
        return a.Equals(b, StringComparison.InvariantCultureIgnoreCase);     // FLAW
    }

    public bool MatchOrdinal(string a, string b)
    {
        return a.Equals(b, StringComparison.OrdinalIgnoreCase);              // OK
    }
}

Remediation

Replace CurrentCulture[IgnoreCase] / InvariantCulture[IgnoreCase] with Ordinal / OrdinalIgnoreCase when comparing invariant data. Keep the culture-aware comparators only for text that is shown to a user in their language.