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:
Ordinalcompara 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(eCurrentCultureIgnoreCase) 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.InvariantCultureusa 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:
| Escape | Significado |
|---|---|
\n | Nova linha (line feed) |
\r | Retorno de carro |
\t | Tabulação |
\\ | Barra invertida |
\" | Aspa dupla |
\' | Aspa simples (só necessária em um literal char) |
\0 | Caractere nulo |
\uXXXX | Caractere UTF-16 por código hexadecimal de 4 dígitos, por exemplo \u00e9 |
\U0001F44D | Caractere por código hexadecimal de 8 dígitos; acima de U+FFFF ele vira dois valores char |
\xH a \xHHHH | Caractere por 1 a 4 dígitos hexadecimais (evite: o tamanho é ambíguo) |
\a, \b, \f, \v | Alerta, backspace, avanço de página, tabulação vertical |
\e | Caractere 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.