Cadeias de caracteres C#

Gorjeta

Este artigo faz parte da seção Conceitos Básicos para desenvolvedores que já conhecem pelo menos uma linguagem de programação e estão aprendendo C#. Se você é novo em programação, comece com os tutoriais Comece agora.

Vindo de Java ou C++? Um C# string é um tipo de referência imutável apoiado por String. UTF-16 é a codificação na memória, semelhante à String de Java. Ao contrário de C/C++, as cadeias de caracteres não são terminadas em nulo e não se decompõem em ponteiros.

Uma cadeia de caracteres é uma sequência de caracteres. Em C#, string é a palavra-chave de idioma para o System.String tipo. Cada literal de cadeia de caracteres que você escreve produz uma System.String instância.

string vs.String

A string palavra-chave e o nome do String tipo referem-se ao mesmo tipo. Eles compilam para a mesma linguagem intermediária (IL).

// The 'string' keyword is an alias for System.String. The two are identical.
string a = "hello";
String b = "hello";

Console.WriteLine(a == b);                // True
Console.WriteLine(typeof(string) == typeof(String)); // True

Prefira a string palavra-chave em seu próprio código. Ela é consistente com as outras palavras-chave internas de tipo (int, bool, double) e funciona sem a diretiva using System;.

Cadeias de caracteres são imutáveis

Imutável significa que o valor não pode ser alterado depois de criado. Depois de criar um string, você não poderá alterar seus caracteres. Métodos como ToUpperInvariant, Replace, e SubstringTrim retornam uma nova cadeia de caracteres que contém o valor modificado. A instância original permanece a mesma.

string greeting = "hello";

// ToUpper returns a *new* string. The original is unchanged.
string shouted = greeting.ToUpperInvariant();

Console.WriteLine(greeting);  // hello
Console.WriteLine(shouted);   // HELLO

Como as cadeias de caracteres são imutáveis, você pode compartilhá-las com segurança entre métodos e threads. Essa imutabilidade explica por que o string tipo se comporta como um tipo de valor no uso diário, mesmo sendo um tipo de referência.

Quando você cria uma cadeia de caracteres de muitas partes pequenas em um loop, use StringBuilder para acrescentar no local e produzir uma única cadeia de caracteres no final:

// For many sequential edits, StringBuilder avoids allocating a new string each time.
var builder = new StringBuilder();
for (int i = 1; i <= 3; i++)
{
    builder.Append("item ").Append(i).Append(';');
}
string result = builder.ToString();
Console.WriteLine(result);    // item 1;item 2;item 3;

Literais de cadeia de caracteres

O C# oferece quatro formulários literais. Cada forma se adequa a um conteúdo diferente. Como um guia rápido:

  • Use literais regulares para texto curto e simples com no máximo algumas sequências de escape.
  • Use literais verbatim quando as barras invertidas dominarem o conteúdo, como caminhos Windows ou padrões regex.
  • Use literais de string bruta para texto de várias linhas ou formatado estruturalmente, como JSON embutido, SQL, XML ou blocos de mensagens formatados.
  • Adicione um $ prefixo a qualquer um dos literais mencionados acima para obter uma cadeia de caracteres interpolada quando precisar inserir valores.
  • Adicione o sufixo u8 a um literal para produzir uma sequência de bytes em UTF-8 (uma ReadOnlySpan<T> de byte) para APIs orientadas a bytes. Consulte literais de cadeia de caracteres UTF-8 na referência de idioma para obter detalhes.

Literais regulares e sequências de escape

Um literal de cadeia de caracteres regular é colocado entre aspas duplas. A barra invertida inicia uma sequência de escape:

// Common escape sequences inside a regular string literal.
string tabbed   = "name:\tAda";          // \t  tab
string twoLines = "line 1\nline 2";      // \n  newline
string quoted   = "She said \"hi\".";    // \"  literal quote
string path     = "C:\\src\\app";        // \\  literal backslash

Console.WriteLine(tabbed);
Console.WriteLine(twoLines);
Console.WriteLine(quoted);
Console.WriteLine(path);

As sequências de escape comuns incluem \n (nova linha), \t (tabulação), \" (aspas literais), \\ (barra invertida literal), \0 (caractere nulo) e sequências de escape Unicode (\uXXXX, \UXXXXXXXX).

A partir do C# 13, \e representa o caractere de controle ESC (U+001B). É o byte inicial para sequências de escape do terminal ANSI:

// Beginning in C# 13, \e represents the ESC control character (U+001B).
// It's used to start ANSI terminal escape sequences.
string esc = "\e[31mError\e[0m: file missing";

Console.WriteLine(esc);                  // ESC[31mError ESC[0m: file missing
Console.WriteLine((int)'\e');          // 27

Use um literal comum quando o texto for curto e contiver apenas algumas sequências de escape. Quando os caracteres de escape começarem a ultrapassar os caracteres visíveis em número, mude para um literal verbatim ou raw.

Literais textuais

Um literal verbatim recebe o prefixo @. As barras invertidas são tratadas literalmente, o que é útil para caminhos do Windows e padrões de expressões regulares:

// A verbatim string literal (@) treats backslashes literally.
// Useful for Windows paths and regular expressions.
string winPath = @"C:\src\app\readme.md";
string pattern = @"\d{3}-\d{4}";

Console.WriteLine(winPath);
Console.WriteLine(pattern);

Para inserir uma citação literal dentro de uma cadeia de caracteres verbatim, dobre-a: @"She said ""hi"".". Cadeias de caracteres verbatim também podem abranger várias linhas físicas.

Literais verbatim são a escolha certa quando barras invertidas fazem parte do conteúdo, mas você não tem muitas aspas embutidas. Para textos de várias linhas ou conteúdos com aspas, literais de string bruta geralmente são mais claros.

Literais brutos de cadeia de caracteres

Para qualquer literal que contenha aspas, cílios invertidas ou várias linhas, prefira literais de cadeia de caracteres brutos. Eles eliminam totalmente o ruído de escape, o que os torna a melhor opção para JSON embutido, SQL, XML, padrões de regex e blocos de texto formatados em que o texto de origem deve ter a mesma aparência da saída:

// Raw string literals use three or more quotes and need no escaping.
// The source looks like the output, which is ideal for inline JSON, SQL, XML, and the like.
string json = """
    {
        "name": "Ada",
        "roles": ["admin", "editor"]
    }
    """;

string sql = """
    SELECT Id, Name
    FROM   Users
    WHERE  Name = 'O''Brien'
    """;

Console.WriteLine(json);
Console.WriteLine(sql);

Literais de cadeia de caracteres brutos eliminam sequências de escape e acomodam qualquer formatação e aspas necessárias. Consulte literais de cadeia de caracteres brutos para obter as regras completas.

Cadeias de caracteres interpoladas

Um $ prefixo transforma um literal em uma cadeia de caracteres interpolada. Expressões em {} buracos são avaliadas e seus resultados inseridos, e você pode aplicar especificadores de formato padrão e alinhamento dentro dos buracos. A interpolação também combina com as outras formas literais – use $@"..." para interpolar um literal verbatim ou $"""...""" para interpolar um literal de cadeia de caracteres bruto para saída ricamente formatada:

// The $ prefix evaluates expressions inside { } and inserts their values.
string name = "Ada";
int score = 92;

string greeting = $"Hello, {name}! Your score is {score}.";
// Format specifiers and alignment work inside the holes.
string formatted = $"pi = {Math.PI:F3}, padded = |{name,10}|";

// Combine $ and """ for richly formatted multiline output.
string report = $"""
    Report for {name}
    -----------------
    Score : {score}
    Grade : {(score >= 90 ? "A" : "B")}
    """;

Console.WriteLine(greeting);
Console.WriteLine(formatted);
Console.WriteLine(report);

A interpolação é a maneira recomendada de compor strings a partir de valores no código do dia a dia.

Indexação e char

Uma string é uma sequência de unidades de código UTF-16. O indexador retorna um System.Char, que representa uma única unidade de código UTF-16, não necessariamente um ponto de código Unicode completo. Length retorna a contagem de unidades de código.

// A string is a sequence of UTF-16 code units. s[i] returns one char.
string word = "café";

Console.WriteLine(word.Length);          // 4
Console.WriteLine(word[0]);              // c

foreach (char c in word)
{
    Console.Write($"{c} ");              // c a f é
}
Console.WriteLine();

Para textos que podem conter emojis ou caracteres fora do Plano Multilíngue Básico, itere por rune usando Rune ou por agrupamento de grafemas usando StringInfo. A iteração simples com char funciona para a maioria dos textos ocidentais e para conteúdo predominantemente em ASCII.

Igualdade da cadeia de caracteres

A igualdade em string compara as sequências de caracteres, não as referências:

// String equality compares character sequences, not references.
string left  = "hello";
string right = string.Concat("hel", "lo");

Console.WriteLine(left == right);                                      // True
Console.WriteLine(left.Equals(right, StringComparison.Ordinal));       // True

Para comparações que precisem ser sensíveis à localidade ou a maiúsculas e minúsculas, passe um valor StringComparison explícito. Use StringComparison.Ordinal para valores de protocolo, identificadores e outros textos não linguísticos.

Operações de cadeia de caracteres comuns

Use a tabela a seguir como um guia rápido para operações de cadeia de caracteres diárias em C#:

Category O que ele aborda
Pesquisa Localizar caracteres ou subcadeias, testar prefixos e sufixos
Divisão Dividir uma cadeia de caracteres em subcadeias de caracteres usando separadores
Concatenar Combinar cadeias de caracteres — +, interpolação, Concat, Join
Modify Produzir uma cópia transformada — Replace, , TrimSubstring
Comparar Testar igualdade e ordenação com a direita StringComparison

A superfície de API completa — cada sobrecarga, cada método — está documentada na String referência.

Consulte também