Specify IFormatProvider

ID

csharp.specify_iformatprovider

Severity

low

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

CSharp

Tags

culture, reliability

Description

Reports Parse, TryParse and Format invocations on formattable primitive types or DateTime-family types that omit an IFormatProvider argument. Without an explicit provider these methods fall back to the current culture.

Rationale

A persisted or transmitted value should round-trip regardless of which locale runs the code. double.Parse("1.5") succeeds in en-US but throws FormatException in de-DE because , is the decimal separator there. The same applies to DateTime.Parse and string.Format for dates and numbers.

public class Roundtrip
{
    public double FromText(string s) => double.Parse(s);                                  // FLAW
    public bool   TryFrom(string s, out double v) => double.TryParse(s, out v);            // FLAW
    public string Money(decimal m) => string.Format("{0:C}", m);                           // FLAW (currency)

    public double Inv(string s) => double.Parse(s, CultureInfo.InvariantCulture);          // OK
    public string MoneyInv(decimal m) => string.Format(CultureInfo.InvariantCulture, "{0:C}", m); // OK
}

Remediation

Pass CultureInfo.InvariantCulture for invariant data and CultureInfo.CurrentCulture when intentionally displaying to the user. Prefer the overloads that accept an IFormatProvider for every Parse, TryParse and Format call.