Menu

Interpolação de strings e String.Format em C#: especificadores de formato, alinhamento, cultura

Como funciona a interpolação de strings com $"..." em C#: expressões entre chaves, especificadores de formato como F2, N0, C, D5 e X, alinhamento para tabelas, escape de chaves, string.Format e formatação composta, strings interpoladas verbatim e raw, e formatação para uma cultura específica.

Esta página tem editores executáveis - edite, execute e veja a saída na hora.

A interpolação de strings monta uma string a partir de texto literal e expressões. Prefixe o literal com $, coloque qualquer expressão C# entre chaves, e o valor dela é convertido em texto e inserido:

Saída:

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

A interpolação chegou no C# 6. O compilador a transforma em uma chamada a string.Format ou string.Concat (ou, desde o C# 10, em código de handler mais eficiente), então ela não é mais lenta que montar a string à mão.

A expressão condicional da última linha precisa de parênteses. Dentro de um trecho de interpolação, dois pontos iniciam um especificador de formato, então {x > 10 ? "yes" : "no"} sem parênteses é um erro de compilação.

Especificadores de formato

Depois da expressão, dois pontos e uma string de formato controlam como o valor é escrito. As mesmas strings de formato funcionam com ToString("...") e string.Format.

Saída:

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

Os códigos padrão, cada um opcionalmente seguido de um número de precisão:

CódigoNomeExemploResultado
F ou F2Ponto fixo{3.14159:F2}3.14
N ou N0Número com separadores de grupo{1234.56:N0}1,235
CMoeda (símbolo e padrão da cultura){9.5:C} em en-US$9.50
D5Inteiro preenchido com zeros{42:D5}00042
X, xHexadecimal{255:X}FF
E2Científico{1234.5:E2}1.23E+003
P1Percentual (multiplica por 100){0.256:P1} em en-US25.6%
GGeral (o mais curto){2.50m:G}2.50
RIda e volta (double){0.1:R}0.1

Padrões personalizados montam um formato a partir de marcadores: 0 é um dígito sempre mostrado, # é um dígito mostrado só se for significativo, . é o ponto decimal, , dentro do número ativa os separadores de grupo, e % multiplica por 100. "0.##" mostra até duas casas decimais e descarta os zeros à direita; "#,##0.00" é o formato contábil clássico.

Toda formatação numérica arredonda o valor exibido; a variável em si não muda. Quando um valor fica exatamente na metade (2.25 mostrado com uma casa decimal), runtimes e tipos diferentes podem arredondar o empate de formas diferentes, então, se a regra importa, arredonde explicitamente antes com Math.Round(value, 1, MidpointRounding.AwayFromZero) e depois formate.

Datas na interpolação

Valores DateTime recebem strings de formato de data do mesmo jeito:

Saída:

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

Um formato personalizado de TimeSpan exige que os caracteres literais sejam escapados com uma barra invertida, o que em um literal de string comum se escreve \\:. A lista completa dos códigos de data (yyyy, MM, HH, tt...) e os erros que as pessoas cometem com eles (mm é minutos, MM é meses) estão em formato de DateTime.

Alinhamento e preenchimento

Uma vírgula depois da expressão define uma largura mínima de campo. Um número positivo alinha à direita, um negativo alinha à esquerda. Combinado com um formato, ele alinha tabelas em texto puro:

Saída:

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

A sintaxe é {expression,alignment:format}: primeiro o alinhamento, depois o formato. Um valor maior que a largura não é truncado; ele empurra o resto da linha. PadLeft e PadRight fazem o mesmo preenchimento fora da interpolação.

Escapando chaves

Para imprimir uma chave literal, duplique-a: {{ e }}. Isso aparece quando a saída é JSON, CSS ou código:

Saída:

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

Montar JSON à mão assim serve para uma linha de log rápida; para JSON de verdade, use um serializador, que trata corretamente aspas e caracteres especiais dentro de name.

string.Format e formatação composta

Antes do C# 6, a formatação era feita com string.Format, que recebe marcadores numerados e uma lista de argumentos. A mesma sintaxe de formatação composta é aceita por Console.WriteLine, StringBuilder.AppendFormat e TextWriter.Write:

Saída:

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

Prefira a interpolação no código: os valores ficam onde aparecem, então um marcador não tem como apontar para o argumento errado. string.Format continua sendo a ferramenta certa quando o modelo é um dado, como uma mensagem traduzida carregada de um arquivo de recursos. Um índice de marcador sem argumento correspondente ({2} com dois argumentos) lança uma FormatException em tempo de execução.

Cultura: controlando separadores e moeda

A interpolação, o ToString e o string.Format usam por padrão a cultura atual da thread. Em uma máquina configurada em alemão, {1234.5:N2} produz 1.234,50; nos EUA produz 1,234.50. O formato de moeda C usa o símbolo da cultura. Para escolher a cultura explicitamente, capture a string interpolada como FormattableString e formate-a com um provedor:

Saída:

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

Use a cultura do usuário para textos que pessoas leem, e CultureInfo.InvariantCulture para tudo o que outro programa lê. Um CSV gravado com a cultura atual em uma máquina alemã tem vírgulas dentro dos números e fica ilegível em outros lugares. No .NET 6 em diante, string.Create(CultureInfo.InvariantCulture, $"...") faz o mesmo que FormattableString.Invariant, sem o objeto intermediário.

Strings interpoladas verbatim e raw

$ se combina com @ em uma string interpolada verbatim: as barras invertidas são literais e a string pode ocupar várias linhas. O C# 8 em diante aceita as duas ordens ($@ ou @$); o C# 6 e o 7 exigem $@:

Saída:

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

O C# 11 adicionou as raw interpolated strings. Com um $, as chaves marcam expressões como de costume. Com $$, uma chave simples é literal e as expressões precisam de duas chaves, o que deixa legíveis os modelos de JSON e de código:

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

O C# 11 também permite quebras de linha dentro de um trecho de interpolação, então uma expressão longa ou uma expressão switch pode ser dividida em várias linhas.

Erros comuns

  • Esquecer o $. "Total: {total}" imprime as chaves literalmente. O compilador não avisa.
  • Um ternário sem parênteses dentro das chaves: os dois pontos são lidos como separador de formato.
  • Formatar saídas lidas por máquinas com a cultura atual. Vírgulas decimais quebram CSV, JSON e SQL. Use a cultura invariante.
  • Usar ToString() sem formato para dinheiro. 2.5m é impresso como 2.5, não 2.50. Use F2, N2 ou C.
  • Montar strings grandes com interpolação em um laço. Cada iteração cria uma string nova; use StringBuilder ou string.Join.

Perguntas frequentes

O que é interpolação de strings em C#?

Um literal de string prefixado com $ em que as expressões entre chaves são avaliadas e inseridas: $"Total: {price * qty}". Ela foi adicionada no C# 6 e substitui a maioria dos usos de string.Format e da concatenação com +. Qualquer expressão funciona entre as chaves, inclusive chamadas de métodos e acesso a propriedades.

Como formatar um número com 2 casas decimais em C#?

Adicione um especificador de formato depois de dois pontos: $"{price:F2}" imprime 2 dígitos depois do ponto decimal, e $"{price:N2}" faz o mesmo com separadores de milhar. Fora da interpolação, os mesmos códigos funcionam com price.ToString("F2"). Os dois arredondam o valor para exibição sem alterá-lo.

Como escapar chaves em uma string interpolada em C#?

Duplique-as: {{ imprime { e }} imprime }. Por exemplo, $"{{ \"id\": {id} }}" imprime { "id": 42 }. Nas raw interpolated strings do C# 11, você pode começar o literal com $$, para que chaves simples sejam literais e {{expr}} marque uma expressão.

Qual a diferença entre string.Format e interpolação de strings?

Elas produzem o mesmo resultado com os mesmos códigos de formato. string.Format("{0} costs {1:F2}", name, price) se refere aos argumentos pela posição; $"{name} costs {price:F2}" coloca as expressões no próprio texto, então é mais fácil de ler e não tem como errar a ordem dos argumentos. string.Format ainda é necessário quando a própria string de formato vem de um arquivo de recursos ou de um banco de dados.

Por que meu número interpolado aparece com vírgula em vez de ponto?

A interpolação formata com a cultura atual da thread, e muitas culturas, como a do Brasil, usam a vírgula como separador decimal. Para saídas lidas por máquinas (arquivos, JSON, URLs), formate com a cultura invariante: FormattableString.Invariant($"{value:F2}"), ou no .NET 6 em diante string.Create(CultureInfo.InvariantCulture, $"...").

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR