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. Não há um caractere de finalização null ao fim de uma cadeia em C#. Portanto, uma cadeia de caracteres em C# pode ter qualquer número de caracteres nulos inseridos ('\0'). A propriedade Char de uma cadeia de caracteres representa o número de objetos Length que ela contém e 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.

Cadeia de caracteres versus System.String

Em C#, a palavra-chave string é um alias para String. Portanto, String e string são equivalentes, independentemente de ser recomendável usar o alias string fornecido, pois ele funciona mesmo sem using System;. A classe String fornece vários 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 saber mais sobre a palavra-chave, confira cadeia de caracteres. Para obter mais informações sobre o tipo e seus métodos, consulte String.

Declaração e inicialização de cadeias de caracteres

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

// 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 new 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 constante Empty para criar um novo objeto String cuja cadeia de caracteres tem comprimento zero. A representação de cadeia de caracteres literal 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 estático IsNullOrEmpty(String) para verificar o valor de uma cadeia de caracteres antes de tentar acessá-la.

Imutabilidade das cadeias de caracteres

Objetos de cadeia de caracteres são imutáveis: não pode ser alterados após serem criados. Todos os métodos String e operadores C# que aparecem para modificar uma cadeia de caracteres retornam, na verdade, os resultados em um novo objeto de cadeia de caracteres. No exemplo a seguir, quando o conteúdo de s1 e s2 é concatenado para formar uma única cadeia de caracteres, as duas cadeias de caracteres originais são modificadas. O operador += cria uma nova cadeia de caracteres que tem o conteúdo combinado. Esse novo objeto é atribuído à variável s1, e o objeto original que foi atribuído a s1 é liberado para coleta de lixo, pois 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 cadeia de caracteres de "modificação" na verdade é uma nova criação de cadeia de caracteres, você deve ter cuidado ao criar referências em cadeias de caracteres. Se você criar uma referência a uma cadeia de caracteres e "modificar" a cadeia de caracteres original, a referência continuará apontar 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 saber mais sobre como criar novas cadeias de caracteres que se baseiam em modificações, como operações de pesquisa e substituição na cadeia de caracteres original, confira Como modificar o conteúdo da cadeia de caracteres.

Literais de cadeia de caracteres entre aspas

Os literais de cadeia de caracteres entre aspas são iniciar e terminar 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 textuais:

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 de cadeia de caracteres bruta

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. É possível gravar a cadeia de caracteres, incluindo a formatação de espaço em branco, da forma que ela deve aparecer 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 ("""). É permitido que 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.
  • Nos literais de cadeia de caracteres bruta multilinha, qualquer espaço em branco à esquerda das aspas de fechamento é removido.

Os exemplos a seguir demonstram essas 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 é recuado para a esquerda da sequência das 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. Literais de cadeia de caracteres bruta podem ser lidos com mais facilidade por você e outras pessoas, pois serão mais parecidos 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"
  ]
}
""";

Compare esse texto com o texto equivalente em nosso exemplo de serialização JSON, que não usa esse novo recurso.

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 Nulo 0x0000
\a Alerta 0x0007
\b Backspace 0x0008
\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 pelo 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 quatro dígitos hexadecimais, se os caracteres que seguem imediatamente a sequência de escape são dígitos hexadecimais válidos (ou seja, 0 a 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 é "A" ou "a", então a sequência de escape será, em vez disso, 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) impedirá qualquer interpretação errônea possível.

Observação

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

Cadeias de caracteres de formato

Uma cadeia de caracteres de formato é aquela cujo conteúdo pode é determinado dinamicamente no runtime. 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 ({...}) será 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: cadeia de caracteres de interpolação e formatação de composição.

Interpolação de cadeia de caracteres

Disponíveis no C# 6.0 e posterior, as cadeias de caracteres interpoladas são identificadas pelo caractere especial $ e incluem expressões interpoladas entre chaves. Se você não estiver familiarizado com a interpolação de cadeia de caracteres, confira o tutorial Interpolação de cadeia de caracteres – tutorial interativo do C#.

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

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.

A partir do C# 10, 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 precisar conter o caractere { ou }, você poderá usar caracteres extras $ para especificar quantos caracteres { e } iniciam e encerram 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 exibir a distância de um ponto da origem e colocar o ponto dentro de 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.

Formatação de composição

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

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 mais informações sobre formatação de tipos .NET, confira Tipos de formatação em .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 com base em 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. Como o método Substring, Replace retorna, na verdade, uma nova cadeia de caracteres e não a modifica a cadeia de caracteres original. Saiba mais em 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"

Se os métodos String não fornecerem a funcionalidade necessária para modificar caracteres individuais em uma cadeia de caracteres, você poderá usar um objeto StringBuilder para modificar os caracteres individuais "in-loco" e criar uma nova cadeia de caracteres para armazenar os resultados usando os métodos StringBuilder. No exemplo a seguir, suponha que você deva 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 caractere. As cadeias de caracteres vazias geralmente são usadas em vários cenários de programação para representar um campo de texto em branco. Você pode chamar métodos em cadeias de caracteres vazias porque eles são objetos System.String válidos. As 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 provocará uma NullReferenceException. No entanto, você pode usar cadeias de caracteres nulas em operações de comparação e concatenaçã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 lançada:

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);

Uso do stringBuilder para a criação rápida de cadeias de caracteres

As operações de cadeia de caracteres no .NET são altamente otimizadas e, na maioria dos casos, não afetam o desempenho de forma significativa. 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 desempenho melhor se o programa executa várias manipulações de cadeia de caracteres. A cadeia de caracteres StringBuilder também permite reatribuir caracteres individuais, o que o tipo de dados String interno não dá suporte. 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 com base em 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

Uma vez que 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 String, mas estão disponíveis mesmo assim. Você também pode usar a expressão de consulta LINQ em cadeias de caracteres. Para saber mais, confira LINQ e cadeias de caracteres.