Specify Culture

ID

csharp.specify_culture

Severity

low

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

CSharp

Tags

culture, reliability

Description

Reports culture-sensitive calls that omit a CultureInfo argument: string.ToUpper(), string.ToLower(), and the parameterless ToString() on numeric or DateTime values. These overloads use the current culture, so the result depends on the locale of whoever runs the code.

Rationale

Casing rules and number/date formatting differ by locale. Code that round-trips a value through int.ToString() and int.Parse(…​) works in en-US but fails in de-DE, where the decimal separator is , and a value of 1.5 is rejected. Casing under tr-TR famously changes i to İ, breaking string equality.

public class Formatter
{
    public string Upper(string s)    => s.ToUpper();                          // FLAW
    public string Lower(string s)    => s.ToLower();                          // FLAW
    public string Format(int x)      => x.ToString();                         // FLAW

    public string InvUpper(string s) => s.ToUpper(CultureInfo.InvariantCulture); // OK
    public string InvFmt(int x)      => x.ToString(CultureInfo.InvariantCulture); // OK
}

Remediation

For invariant data, pass CultureInfo.InvariantCulture. For user-visible display, pass CultureInfo.CurrentCulture deliberately. For string casing prefer ToUpperInvariant() / ToLowerInvariant() when the result is used for identifiers or comparison keys.