Menu

Interpolazione di stringhe e String.Format in C#: formati, allineamento, cultura

Come funziona l'interpolazione di stringhe $"..." in C#: espressioni tra graffe, specificatori di formato come F2, N0, C, D5 e X, allineamento per le tabelle, escape delle graffe, string.Format e formattazione composita, stringhe interpolate verbatim e raw, e formattazione per una cultura specifica.

Questa pagina include editor eseguibili: modifica, esegui e vedi subito l'output.

L'interpolazione di stringhe costruisce una stringa a partire da testo letterale ed espressioni. Metti $ davanti al letterale, scrivi una qualsiasi espressione C# tra graffe, e il suo valore viene convertito in testo e inserito:

Output:

Hello, Maya!
3 items at 4.5 = 13.5
Name has 4 letters, upper: MAYA
Free shipping: yes

L'interpolazione è arrivata in C# 6. Il compilatore la trasforma in una chiamata a string.Format o string.Concat (oppure, da C# 10, in codice handler più efficiente), quindi non è più lenta che costruire la stringa a mano.

L'espressione condizionale nell'ultima riga ha bisogno delle parentesi. Dentro uno spazio di interpolazione, i due punti iniziano uno specificatore di formato, quindi {x > 10 ? "yes" : "no"} senza parentesi è un errore di compilazione.

Specificatori di formato

Dopo l'espressione, i due punti e una stringa di formato controllano come viene scritto il valore. Le stesse stringhe di formato funzionano con ToString("...") e string.Format.

Output:

1234567.89
1,234,567.89
1,234,568
00042
FF
00ff
1.23E+006
0.813
81.3%
1,234,567.89
007.5
3.1

I codici standard, ognuno seguito facoltativamente da un numero di precisione:

CodiceNomeEsempioRisultato
F o F2Virgola fissa{3.14159:F2}3.14
N o N0Numero con separatori delle migliaia{1234.56:N0}1,235
CValuta (simbolo e formato della cultura){9.5:C} in en-US$9.50
D5Intero con zeri iniziali{42:D5}00042
X, xEsadecimale{255:X}FF
E2Scientifico{1234.5:E2}1.23E+003
P1Percentuale (moltiplica per 100){0.256:P1} in en-US25.6%
GGenerale (il più breve){2.50m:G}2.50
RRound-trip (double){0.1:R}0.1

I formati personalizzati costruiscono un formato a partire da segnaposto: 0 è una cifra sempre mostrata, # è una cifra mostrata solo se significativa, . è il separatore decimale, , dentro il numero attiva i separatori delle migliaia, e % moltiplica per 100. "0.##" mostra fino a due decimali ed elimina gli zeri finali; "#,##0.00" è il classico formato contabile.

Tutta la formattazione numerica arrotonda il valore mostrato; la variabile in sé resta invariata. Quando un valore sta esattamente a metà (2.25 mostrato con un decimale), runtime e tipi diversi possono arrotondare il pareggio in modo diverso, quindi se la regola conta arrotonda prima in modo esplicito con Math.Round(value, 1, MidpointRounding.AwayFromZero) e poi formatta.

Date nell'interpolazione

I valori DateTime accettano allo stesso modo le stringhe di formato per le date:

Output:

2026-09-24
24/09/2026 16:05
Thu, Sep 24
Shipped at 16:05 on Thursday
ETA 02:10
2.2 hours

Un formato personalizzato di TimeSpan richiede che i caratteri letterali siano preceduti da un backslash, che in un letterale stringa normale si scrive \\:. L'elenco completo dei codici per le date (yyyy, MM, HH, tt...) e gli errori tipici (mm sono i minuti, MM i mesi) si trovano in formato DateTime.

Allineamento e riempimento

Una virgola dopo l'espressione imposta una larghezza minima del campo. Un numero positivo allinea a destra, un numero negativo allinea a sinistra. Insieme a un formato, permette di incolonnare tabelle in testo semplice:

Output:

Item          |  Price| Sold
----------------------------
Espresso      |   2.40|  118
Latte         |   3.60|   64
Hot chocolate |   4.25|    9

La sintassi è {expression,alignment:format}: prima l'allineamento, poi il formato. Un valore più lungo della larghezza non viene troncato; sposta in avanti il resto della riga. PadLeft e PadRight fanno lo stesso riempimento fuori dall'interpolazione.

Escape delle graffe

Per stampare una graffa letterale, raddoppiala: {{ e }}. Capita quando l'output è JSON, CSS o codice:

Output:

{ "id": 42, "name": "Ana" }
Set literal: {1, 2, 3}
{42}

Costruire JSON a mano in questo modo va bene per una rapida riga di log; per il JSON vero usa un serializzatore, che gestisce correttamente le virgolette e i caratteri speciali dentro name.

string.Format e formattazione composita

Prima di C# 6 la formattazione si faceva con string.Format, che accetta segnaposto numerati e una lista di argomenti. La stessa sintassi di formattazione composita è accettata da Console.WriteLine, StringBuilder.AppendFormat e TextWriter.Write:

Output:

Notebook x4: 14.00
Notebook  |  3.50
echo echo !
Dear Leo, your order #000731 has shipped.

Nel codice preferisci l'interpolazione: i valori stanno dove compaiono, quindi un segnaposto non può puntare all'argomento sbagliato. string.Format resta lo strumento giusto quando il modello è un dato, come un messaggio tradotto caricato da un file di risorse. Un indice di segnaposto senza un argomento corrispondente ({2} con due argomenti) lancia una FormatException in esecuzione.

Cultura: controllare separatori e valuta

Interpolazione, ToString e string.Format usano tutti di default la cultura corrente del thread. Su una macchina impostata in tedesco (o in italiano), {1234.5:N2} produce 1.234,50; negli Stati Uniti produce 1,234.50. Il formato valuta C usa il simbolo della cultura. Per scegliere la cultura in modo esplicito, cattura la stringa interpolata come FormattableString e formattala con un provider:

Output:

Total: 1,234.50
Total: 1.234,50
$1,234.50
1.234,50
1234.5,0.75

Usa la cultura dell'utente per il testo che leggono le persone, e CultureInfo.InvariantCulture per tutto ciò che legge un altro programma. Un CSV scritto con la cultura corrente su una macchina tedesca ha virgole dentro i numeri ed è illeggibile altrove. Su .NET 6 e successivi, string.Create(CultureInfo.InvariantCulture, $"...") fa lo stesso di FormattableString.Invariant senza l'oggetto intermedio.

Stringhe interpolate verbatim e raw

$ si combina con @ per una stringa interpolata verbatim: i backslash sono letterali e la stringa può estendersi su più righe. C# 8 e successivi accettano entrambi gli ordini ($@ o @$); C# 6 e 7 richiedono $@:

Output:

C:\Users\ana\Reports\2026\summary.txt
Report for ana
Year: 2026

C# 11 ha aggiunto le stringhe interpolate raw. Con un solo $, le graffe indicano le espressioni come al solito. Con $$, una graffa singola è letterale e le espressioni richiedono due graffe, il che rende leggibili i modelli JSON e di codice:

// C# 11 and later
int id = 42;
string name = "Ana";
string json = $$"""
    {
      "id": {{id}},
      "name": "{{name}}"
    }
    """;

C# 11 permette anche di andare a capo dentro uno spazio di interpolazione, così un'espressione lunga o un'espressione switch si può dividere su più righe.

Errori comuni

  • Dimenticare il $. "Total: {total}" stampa le graffe letteralmente. Il compilatore non avvisa.
  • Un operatore ternario senza parentesi dentro le graffe: i due punti vengono letti come separatore del formato.
  • Formattare l'output per le macchine con la cultura corrente. Le virgole decimali rompono CSV, JSON e SQL. Usa la cultura invariante.
  • Usare ToString() senza formato per gli importi. 2.5m viene stampato come 2.5, non 2.50. Usa F2, N2 o C.
  • Costruire stringhe grandi con l'interpolazione in un ciclo. Ogni iterazione crea una nuova stringa; usa StringBuilder o string.Join.

Domande frequenti

Cos'è l'interpolazione di stringhe in C#?

Un letterale stringa preceduto da $ in cui le espressioni tra graffe vengono valutate e inserite: $"Total: {price * qty}". È stata aggiunta in C# 6 e sostituisce la maggior parte degli usi di string.Format e della concatenazione con +. Tra le graffe funziona qualsiasi espressione, comprese chiamate di metodo e accesso a proprietà.

Come formatto un numero con 2 cifre decimali in C#?

Aggiungi uno specificatore di formato dopo i due punti: $"{price:F2}" stampa 2 cifre dopo il separatore decimale, e $"{price:N2}" fa lo stesso con i separatori delle migliaia. Fuori dall'interpolazione, gli stessi codici funzionano con price.ToString("F2"). Entrambi arrotondano il valore per la visualizzazione senza modificarlo.

Come faccio l'escape delle graffe in una stringa interpolata C#?

Raddoppiale: {{ stampa { e }} stampa }. Per esempio $"{{ \"id\": {id} }}" stampa { "id": 42 }. Nelle stringhe interpolate raw di C# 11 puoi invece iniziare il letterale con $$, così le graffe singole sono letterali e {{expr}} indica un'espressione.

Che differenza c'è tra string.Format e l'interpolazione di stringhe?

Producono lo stesso risultato con gli stessi codici di formato. string.Format("{0} costs {1:F2}", name, price) fa riferimento agli argomenti per posizione; $"{name} costs {price:F2}" mette le espressioni direttamente nel testo, quindi si legge più facilmente e non può sbagliare l'ordine degli argomenti. string.Format serve ancora quando la stringa di formato stessa arriva da un file di risorse o da un database.

Perché il mio numero interpolato mostra una virgola invece di un punto?

L'interpolazione formatta con la cultura corrente del thread, e molte culture, compresa quella italiana, usano la virgola come separatore decimale. Per l'output letto da programmi (file, JSON, URL), formatta con la cultura invariante: FormattableString.Invariant($"{value:F2}"), oppure su .NET 6 e successivi string.Create(CultureInfo.InvariantCulture, $"...").

Illustrazione dei linguaggi di programmazione di Coddy

Impara a programmare con Coddy

INIZIA