Compartilhar via


Cadeias de caracteres e literais de cadeia de caracteres

Uma cadeia de caracteres é um objeto do tipo String cujo valor é texto. Internamente, o texto é armazenado como uma coleção sequencial somente leitura de objetos Char. A propriedade Length de uma cadeia de caracteres representa o número de objetos Char que ela contém, não o número de caracteres Unicode. Para acessar os pontos de código Unicode individuais em uma cadeia de caracteres, use o objeto StringInfo.

string vs. System.String

Em C#, a palavra-chave string é um alias para String; portanto, String e string são equivalentes. Use o alias fornecido string como ele funciona mesmo sem using System;. A classe String fornece muitos métodos para criar, manipular e comparar cadeias de caracteres com segurança. Além disso, a linguagem C# sobrecarrega alguns operadores para simplificar operações comuns de cadeia de caracteres. Para obter mais informações sobre a palavra-chave, consulte string. Para obter mais informações sobre o tipo e seus métodos, consulte String.

Declarando e inicializando cadeias de caracteres

Você pode declarar e inicializar cadeias de caracteres de várias maneiras, conforme mostrado no exemplo a seguir:

// Declare without initializing.
string message1;

// Initialize to null.
string? message2 = null;

// Initialize as an empty string.
// Use the Empty constant instead of the literal "".
string message3 = System.String.Empty;

// Initialize with a regular string literal.
string oldPath = "c:\\Program Files\\Microsoft Visual Studio 8.0";

// Initialize with a verbatim string literal.
string newPath = @"c:\Program Files\Microsoft Visual Studio 9.0";

// Use System.String if you prefer.
System.String greeting = "Hello World!";

// In local variables (i.e. within a method body)
// you can use implicit typing.
var temp = "I'm still a strongly-typed System.String!";

// Use a const string to prevent 'message4' from
// being used to store another string value.
const string message4 = "You can't get rid of me!";

// Use the String constructor only when creating
// a string from a char*, char[], or sbyte*. See
// System.String documentation for details.
char[] letters = { 'A', 'B', 'C' };
string alphabet = new string(letters);

Você não usa o operador novo para criar um objeto de cadeia de caracteres, exceto ao inicializar a cadeia de caracteres com uma matriz de caracteres.

Inicialize uma cadeia de caracteres com o valor Empty constante para criar um novo objeto String cuja cadeia de caracteres é de comprimento zero. O literal de cadeia de caracteres de uma cadeia de caracteres de comprimento zero é "". Ao inicializar cadeias de caracteres com o valor Empty em vez de nulo, você poderá reduzir as chances de uma NullReferenceException ocorrer. Use o método de IsNullOrEmpty(String) estático para verificar o valor de uma cadeia de caracteres antes de tentar acessá-la.

Imutabilidade de cadeias de caracteres

Objetos de cadeia de caracteres são imutáveis: eles não podem ser alterados depois de criados. Todos os métodos String e operadores C# que parecem modificar uma cadeia de caracteres realmente retornam os resultados em um novo objeto de cadeia de caracteres. No exemplo a seguir, quando o conteúdo de s1 e s2 são concatenados para formar uma única cadeia de caracteres, as duas cadeias de caracteres originais não são modificadas. O operador += cria uma nova cadeia de caracteres que contém o conteúdo combinado. Esse novo objeto é atribuído à variável s1e o objeto original atribuído a s1 é liberado para coleta de lixo porque nenhuma outra variável contém uma referência a ele.

string s1 = "A string is more ";
string s2 = "than the sum of its chars.";

// Concatenate s1 and s2. This actually creates a new
// string object and stores it in s1, releasing the
// reference to the original object.
s1 += s2;

System.Console.WriteLine(s1);
// Output: A string is more than the sum of its chars.

Como uma "modificação" de cadeia de caracteres é, na verdade, uma nova criação de cadeia de caracteres, você deve ter cuidado ao criar referências a cadeias de caracteres. Se você criar uma referência a uma cadeia de caracteres e depois "modificar" a cadeia de caracteres original, a referência continuará apontando para o objeto original em vez do novo objeto que foi criado quando a cadeia de caracteres foi modificada. O código a seguir ilustra esse comportamento:

string str1 = "Hello ";
string str2 = str1;
str1 += "World";

System.Console.WriteLine(str2);
//Output: Hello

Para obter mais informações sobre como criar novas cadeias de caracteres baseadas em modificações como operações de pesquisa e substituição na cadeia de caracteres original, consulte Como modificar o conteúdo da cadeia de caracteres.

Literais de cadeia de caracteres entre aspas

Os literais de cadeia de caracteres entre aspas iniciam e terminam com um único caractere de aspas duplas (") na mesma linha. Literais de cadeia de caracteres entre aspas são mais adequados para cadeias de caracteres que se encaixam em uma única linha e não incluem sequências de escape. Um literal de cadeia de caracteres entre aspas deve inserir caracteres de escape, conforme demonstrado no exemplo a seguir:

string columns = "Column 1\tColumn 2\tColumn 3";
//Output: Column 1        Column 2        Column 3

string rows = "Row 1\r\nRow 2\r\nRow 3";
/* Output:
    Row 1
    Row 2
    Row 3
*/

string title = "\"The \u00C6olean Harp\", by Samuel Taylor Coleridge";
//Output: "The Æolean Harp", by Samuel Taylor Coleridge

Literais de cadeia de caracteres textuais

Literais de cadeia de caracteres verbatim são mais convenientes para cadeias de caracteres de várias linhas, cadeias de caracteres que contêm caracteres de barra invertida ou aspas duplas inseridas. Cadeias de caracteres verbatim preservam caracteres de nova linha como parte do texto da cadeia de caracteres. Use aspas duplas para inserir uma marca de aspas simples dentro de uma cadeia de caracteres textual. O exemplo a seguir mostra alguns usos comuns para cadeias de caracteres verbatim:

string title = "\"The \u00C6olean Harp\", by Samuel Taylor Coleridge";
//Output: "The Æolean Harp", by Samuel Taylor Coleridge

string filePath = @"C:\Users\scoleridge\Documents\";
//Output: C:\Users\scoleridge\Documents\

string text = @"My pensive SARA ! thy soft cheek reclined
    Thus on mine arm, most soothing sweet it is
    To sit beside our Cot,...";
/* Output:
My pensive SARA ! thy soft cheek reclined
    Thus on mine arm, most soothing sweet it is
    To sit beside our Cot,...
*/

string quote = @"Her name was ""Sara.""";
//Output: Her name was "Sara."

Literais brutos de cadeia de caracteres

A partir do C# 11, é possível usar literais de cadeia de caracteres bruta para criar cadeias de caracteres multilinha com mais facilidade ou usar quaisquer caracteres que exijam sequências de escape. Literais de cadeia de caracteres bruta removem a necessidade de usar sequências de escape. Você pode escrever a cadeia de caracteres, incluindo a formatação de espaço em branco, como deseja que ela apareça na saída. Um literal de cadeia de caracteres bruta:

  • Inicia e termina com uma sequência de pelo menos três caracteres de aspas duplas ("""). Você pode usar mais de três caracteres consecutivos iniciem e terminem a sequência para dar suporte a literais de cadeia de caracteres que contêm três (ou mais) caracteres de aspas repetidos.
  • Literais de cadeia de caracteres bruta de linha única exigem os caracteres de aspas de abertura e fechamento na mesma linha.
  • Literais de cadeia de caracteres bruta multilinha exigem caracteres de aspas de abertura e fechamento em suas próprias linhas.
  • Em literais de cadeia de caracteres brutos de várias linhas, qualquer espaço em branco à esquerda das aspas de fechamento é removido de todas as linhas do literal da cadeia de caracteres bruta.
  • Em literais de cadeia de caracteres brutos de várias linhas, o espaço em branco após a citação de abertura na mesma linha é ignorado.
  • Em literais de cadeia de caracteres brutos de várias linhas, somente as linhas de espaço em branco após a cotação de abertura são incluídas no literal da cadeia de caracteres.

Os exemplos a seguir demonstram estas regras:

string singleLine = """Friends say "hello" as they pass by.""";
string multiLine = """
    "Hello World!" is typically the first program someone writes.
    """;
string embeddedXML = """
       <element attr = "content">
           <body style="normal">
               Here is the main text
           </body>
           <footer>
               Excerpts from "An amazing story"
           </footer>
       </element >
       """;
// The line "<element attr = "content">" starts in the first column.
// All whitespace left of that column is removed from the string.

string rawStringLiteralDelimiter = """"
    Raw string literals are delimited 
    by a string of at least three double quotes,
    like this: """
    """";

Os exemplos a seguir demonstram os erros do compilador relatados com base nessas regras:

// CS8997: Unterminated raw string literal.
var multiLineStart = """This
    is the beginning of a string 
    """;

// CS9000: Raw string literal delimiter must be on its own line.
var multiLineEnd = """
    This is the beginning of a string """;

// CS8999: Line does not start with the same whitespace as the closing line
// of the raw string literal
var noOutdenting = """
    A line of text.
Trying to outdent the second line.
    """;

Os dois primeiros exemplos são inválidos porque literais de cadeia de caracteres bruta multilinha exigem a sequência de aspas de abertura e fechamento em sua própria linha. O terceiro exemplo é inválido porque o texto é retirado da sequência de aspas de fechamento.

Você deve considerar literais de cadeia de caracteres bruta ao gerar texto que inclua caracteres que exigem sequências de escape ao usar literais de cadeia de caracteres entre aspas ou literais de cadeia de caracteres verbatim. Os literais de cadeia de caracteres bruta são lidos com mais facilidade por você e outras pessoas, pois se parecem com o texto de saída. Por exemplo, considere o seguinte código que inclui uma cadeia de caracteres de JSON formatado:

string jsonString = """
{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Summary": "Hot",
  "DatesAvailable": [
    "2019-08-01T00:00:00-07:00",
    "2019-08-02T00:00:00-07:00"
  ],
  "TemperatureRanges": {
    "Cold": {
      "High": 20,
      "Low": -10
    },
    "Hot": {
      "High": 60,
      "Low": 20
    }
            },
  "SummaryWords": [
    "Cool",
    "Windy",
    "Humid"
  ]
}
""";

Sequências de escape de cadeia de caracteres

Sequência de escape Nome do caractere Codificação Unicode
\' Aspas simples 0x0027
\" Aspas duplas 0x0022
\\ Barra invertida 0x005C
\0 Zero 0x0000
\a Alerta 0x0007
\b Backspace 0x0008
\e Escape 0x001B
\f Avanço de formulário 0x000C
\n Nova linha 0x000A
\r Retorno de carro 0x000D
\t Guia horizontal 0x0009
\v Guia vertical 0x000B
\u Sequência de escape Unicode (UTF-16) \uHHHH (intervalo: 0000 – FFFF; exemplo: \u00E7 = "ç")
\U Sequência de escape Unicode (UTF-32) \U00HHHHHH (intervalo: 000000 - 10FFFF; exemplo: \U0001F47D = "👽")
\x Sequência de escape Unicode semelhante a "\u", exceto com comprimento variável \xH[H][H][H] (intervalo: 0 – FFFF; exemplo: \x00E7 ou \x0E7 ou \xE7 = "ç")

Aviso

Ao usar a sequência de escape \x e especificar menos de 4 dígitos hexadecimais, se os caracteres que seguem imediatamente a sequência de escape forem dígitos hexadecimais válidos (ou seja, 0-9, A-F e a-f), eles serão interpretados como sendo parte da sequência de escape. Por exemplo, \xA1 produz "\", que é o ponto de código U+00A1. No entanto, se o próximo caractere for "A" ou "a", a sequência de escape será interpretada como sendo \xA1A e produzirá "ਚ", que é o ponto de código U+0A1A. Nesses casos, especificar todos os quatro dígitos hexadecimais (por exemplo, \x00A1) impede qualquer possível interpretação incorreta.

Nota

No tempo de compilação, as cadeias de caracteres brutas e verbatim são convertidas em comuns com todas as mesmas sequências de escape. Portanto, se você exibir uma cadeia de caracteres literal ou bruta na janela de inspeção do depurador, você verá os caracteres de escape que foram adicionados pelo compilador, não a versão literal ou bruta do seu código-fonte. Por exemplo, a cadeia de caracteres textual @"C:\files.txt" será exibida na janela de inspeção como "C:\\files.txt".

Formatar cadeias de caracteres

Uma cadeia de caracteres de formato é uma cadeia de caracteres cujo conteúdo é determinado dinamicamente em tempo de execução. Cadeias de caracteres de formato são criadas incorporando expressões interpoladas ou espaços reservados dentro de chaves dentro em uma cadeia de caracteres. Tudo dentro das chaves ({...}) é resolvido para um valor e uma saída como uma cadeia de caracteres formatada no runtime. Há dois métodos para criar cadeias de caracteres de formato: interpolação de cadeia de caracteres e formatação composta.

Interpolação de cadeia de caracteres

Você declara cadeias de caracteres interpoladas com o caractere especial $. Uma cadeia de caracteres interpolada inclui expressões interpoladas em chaves. Se você não estiver familiarizado com a interpolação de cadeia de caracteres, consulte a interpolação de cadeia de caracteres – tutorial interativo em C# para obter uma visão geral rápida.

Use a interpolação de cadeia de caracteres para melhorar a legibilidade e a manutenção do código. A interpolação de strings obtém os mesmos resultados que o método String.Format, mas melhora a facilidade de uso e a clareza no código.

var jh = (firstName: "Jupiter", lastName: "Hammon", born: 1711, published: 1761);
Console.WriteLine($"{jh.firstName} {jh.lastName} was an African American poet born in {jh.born}.");
Console.WriteLine($"He was first published in {jh.published} at the age of {jh.published - jh.born}.");
Console.WriteLine($"He'd be over {Math.Round((2018d - jh.born) / 100d) * 100d} years old today.");

// Output:
// Jupiter Hammon was an African American poet born in 1711.
// He was first published in 1761 at the age of 50.
// He'd be over 300 years old today.

Você pode usar a interpolação de cadeia de caracteres para inicializar uma cadeia de caracteres constante quando todas as expressões usadas para espaços reservados também são cadeias de caracteres constantes.

A partir do C# 11, você pode combinar literais de cadeia de caracteres bruta com interpolações de cadeia de caracteres. Você inicia e termina a cadeia de caracteres de formato com três ou mais aspas duplas sucessivas. Se a cadeia de caracteres de saída deve conter o caractere { ou }, você poderá usar caracteres de $ extras para especificar quantos caracteres { e } iniciam e terminam uma interpolação. Qualquer sequência com menos de { ou } caracteres é incluída na saída. O exemplo a seguir mostra como você pode usar esse recurso para mostrar a distância de um ponto em relação à origem e colocar o ponto entre chaves.

int X = 2;
int Y = 3;

var pointMessage = $$"""The point {{{X}}, {{Y}}} is {{Math.Sqrt(X * X + Y * Y)}} from the origin.""";

Console.WriteLine(pointMessage);
// Output:
// The point {2, 3} is 3.605551275463989 from the origin.

Interpolação da cadeia de caracteres textual

Por exemplo, o C# também permite a interpolação de strings verbatim em várias linhas, usando a sintaxe $@ ou @$.

Para interpretar sequências de escape literalmente, use um literal de cadeia de caracteres textual. Uma cadeia de caracteres verbatim interpolada começa com o caractere $ seguido pelo caractere @. Você pode usar os tokens $ e @ em qualquer ordem: tanto $@"..." quanto @$"..." são strings verbatim interpoladas válidas.

var jh = (firstName: "Jupiter", lastName: "Hammon", born: 1711, published: 1761);
Console.WriteLine($@"{jh.firstName} {jh.lastName}
    was an African American poet born in {jh.born}.");
Console.WriteLine(@$"He was first published in {jh.published}
at the age of {jh.published - jh.born}.");

// Output:
// Jupiter Hammon
//     was an African American poet born in 1711.
// He was first published in 1761
// at the age of 50.

Formatação composta

O String.Format utiliza os espaços reservados entre chaves para criar uma cadeia de caracteres de formato. Este exemplo resulta em saída semelhante ao método de interpolação de cadeia de caracteres usado no exemplo anterior.

var pw = (firstName: "Phillis", lastName: "Wheatley", born: 1753, published: 1773);
Console.WriteLine("{0} {1} was an African American poet born in {2}.", pw.firstName, pw.lastName, pw.born);
Console.WriteLine("She was first published in {0} at the age of {1}.", pw.published, pw.published - pw.born);
Console.WriteLine("She'd be over {0} years old today.", Math.Round((2018d - pw.born) / 100d) * 100d);

// Output:
// Phillis Wheatley was an African American poet born in 1753.
// She was first published in 1773 at the age of 20.
// She'd be over 300 years old today.

Para obter mais informações sobre a formatação de tipos .NET, consulte Tipos de Formatação no .NET.

Subcadeias de caracteres

Uma subcadeia de caracteres é qualquer sequência de caracteres contida em uma cadeia de caracteres. Use o método Substring para criar uma nova cadeia de caracteres de uma parte da cadeia de caracteres original. Você pode pesquisar uma ou mais ocorrências de uma subcadeia de caracteres usando o método IndexOf. Use o método Replace para substituir todas as ocorrências de uma subcadeia de caracteres especificada por uma nova cadeia de caracteres. Assim como o método Substring, Replace realmente retorna uma nova cadeia de caracteres e não modifica a cadeia de caracteres original. Para obter mais informações, consulte Como pesquisar cadeias de caracteres e Como modificar o conteúdo da cadeia de caracteres.

string s3 = "Visual C# Express";
System.Console.WriteLine(s3.Substring(7, 2));
// Output: "C#"

System.Console.WriteLine(s3.Replace("C#", "Basic"));
// Output: "Visual Basic Express"

// Index values are zero-based
int index = s3.IndexOf("C");
// index = 7

Acesso a caracteres individuais

Você pode usar a notação de matriz com um valor de índice para adquirir acesso somente leitura a caracteres individuais, como no seguinte exemplo:

string s5 = "Printing backwards";

for (int i = 0; i < s5.Length; i++)
{
    System.Console.Write(s5[s5.Length - i - 1]);
}
// Output: "sdrawkcab gnitnirP"

Caso os métodos String não forneçam a funcionalidade que você precisa para modificar caracteres individuais em uma cadeia de caracteres, você pode usar um objeto StringBuilder para modificar os caracteres individuais diretamente e, em seguida, criar uma nova cadeia de caracteres para armazenar os resultados usando os métodos StringBuilder. No exemplo a seguir, suponha que você deve modificar a cadeia de caracteres original de uma maneira específica e armazenar os resultados para uso futuro:

string question = "hOW DOES mICROSOFT wORD DEAL WITH THE cAPS lOCK KEY?";
System.Text.StringBuilder sb = new System.Text.StringBuilder(question);

for (int j = 0; j < sb.Length; j++)
{
    if (System.Char.IsLower(sb[j]) == true)
        sb[j] = System.Char.ToUpper(sb[j]);
    else if (System.Char.IsUpper(sb[j]) == true)
        sb[j] = System.Char.ToLower(sb[j]);
}
// Store the new string.
string corrected = sb.ToString();
System.Console.WriteLine(corrected);
// Output: How does Microsoft Word deal with the Caps Lock key?

Cadeias de caracteres nulas e cadeias de caracteres vazias

Uma cadeia de caracteres vazia é uma instância de um objeto System.String que contém zero caracteres. Cadeias de caracteres vazias são usadas frequentemente em vários cenários de programação para representar um campo de texto em branco. Você pode chamar métodos em strings vazias porque elas são objetos System.String válidos. Cadeias de caracteres vazias são inicializadas da seguinte maneira:

string s = String.Empty;

Por outro lado, uma cadeia de caracteres nula não se refere a uma instância de um objeto System.String e qualquer tentativa de chamar um método em uma cadeia de caracteres nula causa um NullReferenceException. No entanto, você pode usar cadeias de caracteres nulas em operações de concatenação e comparação com outras cadeias de caracteres. Os exemplos a seguir ilustram alguns casos em que uma referência a uma cadeia de caracteres nula faz e não faz com que uma exceção seja gerada:

string str = "hello";
string? nullStr = null;
string emptyStr = String.Empty;

string tempStr = str + nullStr;
// Output of the following line: hello
Console.WriteLine(tempStr);

bool b = (emptyStr == nullStr);
// Output of the following line: False
Console.WriteLine(b);

// The following line creates a new empty string.
string newStr = emptyStr + nullStr;

// Null strings and empty strings behave differently. The following
// two lines display 0.
Console.WriteLine(emptyStr.Length);
Console.WriteLine(newStr.Length);
// The following line raises a NullReferenceException.
//Console.WriteLine(nullStr.Length);

// The null character can be displayed and counted, like other chars.
string s1 = "\x0" + "abc";
string s2 = "abc" + "\x0";
// Output of the following line: * abc*
Console.WriteLine("*" + s1 + "*");
// Output of the following line: *abc *
Console.WriteLine("*" + s2 + "*");
// Output of the following line: 4
Console.WriteLine(s2.Length);

Usando StringBuilder para criação rápida de cadeia de caracteres

As operações de cadeia de caracteres no .NET são altamente otimizadas e, na maioria dos casos, não afetam significativamente o desempenho. No entanto, em alguns cenários, como loops rígidos que são executados centenas ou milhares de vezes, as operações de cadeia de caracteres podem afetar o desempenho. A classe StringBuilder cria um buffer de cadeia de caracteres que oferece melhor desempenho se o programa executar muitas manipulações de cadeia de caracteres. A string StringBuilder também permite que você reatribua caracteres individuais, algo que o tipo de dados de string padrão não suporta. Esse código, por exemplo, altera o conteúdo de uma cadeia de caracteres sem criar uma nova cadeia de caracteres:

System.Text.StringBuilder sb = new System.Text.StringBuilder("Rat: the ideal pet");
sb[0] = 'C';
System.Console.WriteLine(sb.ToString());
//Outputs Cat: the ideal pet

Neste exemplo, um objeto StringBuilder é usado para criar uma cadeia de caracteres de um conjunto de tipos numéricos:

var sb = new StringBuilder();

// Create a string composed of numbers 0 - 9
for (int i = 0; i < 10; i++)
{
    sb.Append(i.ToString());
}
Console.WriteLine(sb);  // displays 0123456789

// Copy one character of the string (not possible with a System.String)
sb[0] = sb[9];

Console.WriteLine(sb);  // displays 9123456789

Cadeias de caracteres, métodos de extensão e LINQ

Como o tipo String implementa IEnumerable<T>, você pode usar os métodos de extensão definidos na classe Enumerable em cadeias de caracteres. Para evitar a desordem visual, esses métodos são excluídos do IntelliSense para o tipo de String, mas estão disponíveis no entanto. Você também pode usar expressões de consulta LINQ em cadeias de caracteres. Para obter mais informações, consulte LINQ e strings.