Summary#
A number becomes a string with a format specifier: $"{total:F2}" renders 1.5 as "1.50". The same specifier
works through total.ToString("F2") and Convert.ToString(total, "F2") — they are three spellings of one operation.
Signature#
$"{<value>:<format>}"
<value>.ToString(<format>)
Convert.ToString(<value>, <format>)Description#
The specifiers#
A specifier is a letter plus an optional precision, e.g. F2, N0, P1. Precision defaults to 2 where it applies.
| Specifier | 1234.5678 renders as | What it is |
|---|---|---|
F2 | 1234.57 | fixed-point — the everyday one, and what money wants |
N2 | 1,234.57 | number — same as F, plus group separators |
C | ¤1,234.57 | currency |
P2 | 123,456.78 % | percent — multiplies by 100 |
E | 1.234568E+003 | scientific |
G | 1234.5678 | general — the plain digits |
D5 | (integers only) 00042 | decimal digits, zero-padded |
X | (integers only) 2A | hexadecimal |
Three of these behave in ways worth knowing before you rely on them:
- Currency uses
¤, the generic currency sign — not$. Formatting is invariant (see below), and the invariant culture has no country, so it has no currency symbol either. If you want$or€, write it:$"${total:N2}". - A negative currency is wrapped in parentheses:
-1.5renders as(¤1.50), not-¤1.50. DandXare integer-only. Applied to a decimal they raise an error, even for a whole number like0.
Rounding#
Formatting rounds away from zero: 1.005 to two places is 1.01, and -1.005 is -1.01. Because a decimal
holds exact base-10 digits, that is the digit you actually wrote — not the nearest binary approximation of it. A
value that rounds to zero prints as 0, never -0.
It renders the same everywhere#
Formatting is invariant: it does not consult the machine's locale. A price is the same string in the browser, on the server, in a log line, and in a test — and it does not change when a user in another country opens the page.
That is also why formatting runs in the browser, with no round trip: rendering a grid of prices is local work.
Custom patterns#
A custom pattern like "#,##0.00" or "0.00" also works, and does exactly what it does in C#. Note that a custom
pattern is formatted on the server, so a UI action using one costs a network round trip where a standard specifier
would not — prefer N2 over #,##0.00 when they give the same answer.
Examples#
string PriceLabel(decimal amount) {
return $"{amount:N2}";
}
// PriceLabel(1234.5m) -> "1,234.50"string Summary(decimal rate, int reference) {
return $"{rate:P1} · ref {reference:D6}";
}
// Summary(0.0825m, 42) -> "8.3 % · ref 000042"See also#
- String interpolation & format specifiers — the
$"…"string itself - decimal — why exact base-10 digits are what makes
F2trustworthy - execution side — why this runs in the browser