Menu

String em C#: Length, comparação, caracteres de escape, strings verbatim e multilinha

Como as strings funcionam em C#: imutabilidade, Length e índices, comparar com ==, Equals e string.Compare, caracteres de escape, strings verbatim com @ e texto multilinha, raw string literals, verificações de null e vazio e percorrer caracteres.

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

Uma string em C# é uma sequência de caracteres UTF-16 (valores char). Ela é um tipo de referência, mas se comporta como um valor nos pontos que importam: ela é imutável, e == compara o texto em vez da identidade do objeto. string é a palavra-chave de C# para o tipo .NET System.String; os dois são intercambiáveis.

Saída:

Porto
5
0
*****
hi
Porto has 5 letters

Strings são imutáveis

Nenhum método muda uma string no lugar. ToUpper, Replace, Trim e todos os outros métodos retornam uma string nova e deixam a original intacta. Esquecer de usar o valor de retorno é um bug muito comum com strings:

Saída:

[  maya  ]
[MAYA]
tea
tea and cake

A imutabilidade torna as strings seguras para compartilhar entre threads e para usar como chaves de dicionário. O custo é que montar uma string pedaço por pedaço em um laço cria uma string nova a cada passo; para isso, use StringBuilder.

Length e índices

Length é uma propriedade (sem parênteses). O indexador s[i] retorna o char na posição i, contando a partir de 0, e é somente leitura:

Saída:

7
A
1
IndexOutOfRangeException
XB-2931

O C# 8 em diante também aceita um índice a partir do fim: code[^1] é o último caractere, o mesmo que code[code.Length - 1]. Para pegar vários caracteres de uma vez, veja substring.

Length conta unidades de código UTF-16, não o que um leitor vê como caracteres. A maioria das letras na maioria dos idiomas ocupa uma unidade, mas emojis e alguns sistemas de escrita raros usam duas (um par substituto), então "👍".Length é 2.

Comparando strings

== e != comparam os caracteres, diferenciando maiúsculas de minúsculas. Para qualquer outra coisa, passe um valor StringComparison que diz como comparar:

Saída:

False
False
True
True
apple first
True
False
False
True

Qual comparação usar:

  • Ordinal compara os códigos numéricos dos caracteres. É rápida, previsível e igual em qualquer máquina. Use-a para identificadores, nomes de arquivo, chaves, valores de protocolo e tudo o que não é mostrado a uma pessoa.
  • OrdinalIgnoreCase é a mesma coisa, ignorando maiúsculas e minúsculas. A escolha certa para verificações sem diferenciar maiúsculas e minúsculas, como extensões de arquivo ou cabeçalhos HTTP.
  • CurrentCulture (e CurrentCultureIgnoreCase) segue as regras do idioma do usuário, então ordena as palavras como um dicionário nesse idioma faria. Use-a para ordenar listas mostradas aos usuários.
  • InvariantCulture usa regras que respeitam a cultura, mas não dependem das configurações de idioma do usuário. Ela ainda depende da biblioteca de globalização: o .NET moderno usa ICU, o .NET Framework usa o NLS do Windows, e os dois podem ordenar algumas strings de forma diferente.

string.Compare(a, b) e a.CompareTo(b) sem um StringComparison usam a cultura atual, o que faz os resultados variarem entre máquinas. Evite comparar com a.ToLower() == b.ToLower(): isso aloca duas strings novas e dá respostas erradas em algumas culturas (o i com e sem ponto do turco é o caso clássico).

Chamar a.Equals(b) quando a é null lança uma NullReferenceException, enquanto a == b e o método static string.Equals(a, b) tratam null com segurança.

Caracteres de escape

Dentro de um literal de string comum, uma barra invertida começa uma sequência de escape:

EscapeSignificado
\nNova linha (line feed)
\rRetorno de carro
\tTabulação
\\Barra invertida
\"Aspa dupla
\'Aspa simples (só necessária em um literal char)
\0Caractere nulo
\uXXXXCaractere UTF-16 por código hexadecimal de 4 dígitos, por exemplo \u00e9
\U0001F44DCaractere por código hexadecimal de 8 dígitos; acima de U+FFFF ele vira dois valores char
\xH a \xHHHHCaractere por 1 a 4 dígitos hexadecimais (evite: o tamanho é ambíguo)
\a, \b, \f, \vAlerta, backspace, avanço de página, tabulação vertical
\eCaractere de escape, U+001B (C# 13)

Saída:

Name:	Ana
City:	Porto
She said "hi"
C:\temp\report.txt
cafe = cafe
' is a quote char

Uma sequência não reconhecida como "\d" é um erro de compilação (CS1009, unrecognized escape sequence), que é o que acontece quando um caminho do Windows ou uma expressão regular é escrito como string comum.

Strings verbatim e strings multilinha

Prefixar um literal com @ o torna verbatim: as barras invertidas são caracteres literais, e a string pode ocupar várias linhas. O único escape que sobra é "", que produz uma aspa dupla.

Saída:

C:\Users\ana\Documents\notes.txt
\d{3}-\d{4}
He said "ready" and left.
Rua das Flores 12
4050-262 Porto
Portugal
first line
second line

Uma string verbatim multilinha inclui tudo o que está entre as aspas, inclusive a indentação das linhas de continuação, e é por isso que elas normalmente são escritas coladas à margem, como acima. As quebras de linha que ela contém são as do arquivo-fonte, então um arquivo salvo com finais de linha do Windows produz \r\n.

O C# 11 adicionou os raw string literals, que resolvem os dois problemas. Eles começam e terminam com três ou mais aspas duplas, não precisam de escape nenhum e removem a indentação em que as aspas de fechamento estão:

// C# 11 and later
string json = """
    {
      "name": "Ana",
      "path": "C:\temp"
    }
    """;
// The 4 spaces before the closing """ are removed from every line.

Se o próprio conteúdo contém """, comece e termine com quatro aspas. Raw literals também se combinam com interpolação ($"""..."""); veja interpolação de strings.

Null, vazia e espaços em branco

Uma variável string pode ser null (nenhuma string), vazia ("", tamanho 0) ou conter só espaços em branco. Dois auxiliares static verificam esses casos sem risco de NullReferenceException:

Saída:

null    empty: True   blank: True
""      empty: True   blank: True
"   "   empty: False  blank: True
"Ana"   empty: False  blank: False
True

Para validar entradas do usuário, string.IsNullOrWhiteSpace é quase sempre o que você quer. string.Empty e "" são o mesmo valor; qual escrever é questão de estilo.

Percorrendo os caracteres

Uma string é enumerável, então o foreach visita cada char. O tipo char tem métodos static para classificar caracteres:

Saída:

letters=6 digits=4 upper=1 symbols=1
!6202tesnuS

Juntando strings

+ concatena, e funciona com qualquer tipo do outro lado (ele chama ToString()). Para combinar muitos valores, prefira a interpolação ou string.Join:

Saída:

Ana Silva, 31
Ana Silva, 31
AnaSilva
tea | coffee | juice
Total: 23
Total: 5

As duas últimas linhas mostram uma armadilha de precedência: + é avaliado da esquerda para a direita, então quando o lado esquerdo já é uma string, todo + seguinte é concatenação. Coloque parênteses na aritmética dentro de uma concatenação.

Perguntas frequentes

Como obter o tamanho de uma string em C#?

Use a propriedade Length: "hello".Length é 5. É uma propriedade, não um método, então não leva parênteses. Length conta unidades de código UTF-16, então um emoji ou outro caractere fora do Plano Multilíngue Básico conta como 2. Chamá-la em uma string null lança uma NullReferenceException.

Como comparar strings em C#?

a == b compara o texto e diferencia maiúsculas de minúsculas. Para igualdade sem diferenciar maiúsculas e minúsculas, use string.Equals(a, b, StringComparison.OrdinalIgnoreCase). Para ordenar strings, use string.Compare(a, b, StringComparison.Ordinal) ou uma comparação que respeita a cultura, que retorna um número negativo, zero ou um número positivo.

Como escrever uma string multilinha em C#?

Prefixe o literal com @ para torná-lo verbatim: ele pode ocupar várias linhas, as barras invertidas são literais e uma aspa dupla é escrita como "". No C# 11 em diante, os raw string literals delimitados por """ também ocupam várias linhas, removem a indentação comum e não precisam de escape nenhum. Você também pode juntar linhas com \n ou Environment.NewLine.

O que é uma string verbatim em C#?

Um literal de string prefixado com @, como @"C:\Users\ana". As sequências de escape não são processadas, então uma barra invertida é só uma barra invertida, o que a torna a escolha natural para caminhos do Windows e expressões regulares. O único escape dentro dela é "" para uma aspa dupla.

Qual a diferença entre string e String em C#?

Nenhuma. string é o apelido da palavra-chave de C# para o tipo .NET System.String, assim como int é um apelido para System.Int32. A convenção é usar string nas declarações e string.IsNullOrEmpty(...) nas chamadas static, mas os dois compilam exatamente para a mesma coisa.

Quais caracteres de escape C# aceita?

\n quebra de linha, \r retorno de carro, \t tabulação, \\ barra invertida, \" aspa dupla, \' aspa simples, \0 caractere nulo, \uXXXX um caractere UTF-16 pelo código hexadecimal, \U0001F600 um caractere por um código de 8 dígitos (ele vira um par substituto), \a alerta, \b backspace, \f avanço de página, \v tabulação vertical e \e (C# 13) escape. Uma sequência desconhecida como \d é um erro de compilação (CS1009), e é por isso que expressões regulares normalmente são escritas como strings verbatim.

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR