Partilhar via


Strings e literais de string

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 Char objetos 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 pois 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 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 tenha comprimento zero. A representação literal de uma cadeia de caracteres de comprimento zero é "". Ao inicializar cadeias de caracteres com o valor Empty em vez de nulo, você pode reduzir as chances de ocorrência de um NullReferenceException. Use o método IsNullOrEmpty(String) estático para verificar o valor de uma cadeia de caracteres antes de tentar acessá-la.

Imutabilidade das cordas

Os objetos String 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 s1, e o objeto original que foi 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, em seguida, "modificar" a cadeia de caracteres original, a referência continuará a 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 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 entre aspas

Os literais de cadeia entre aspas começam e terminam com um único caractere de aspas duplas (") na mesma linha. Os literais de strings entre aspas são mais adequados para strings que cabem numa única linha e não incluem nenhuma sequência de escape . Uma frase literal entre aspas deve incorporar os caracteres de escape, conforme mostrado 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 verbatim

literais de cadeia de caracteres 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 incorporadas. As cadeias de caracteres verbatinas preservam novos caracteres de linha como parte do texto da cadeia de caracteres. Use aspas duplas para incorporar aspas dentro de uma cadeia de caracteres literal. O exemplo a seguir mostra alguns usos comuns para strings textuais:

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

A partir do C# 11, você pode usar literais de cadeia de caracteres brutos para criar mais facilmente cadeias de caracteres com várias linhas ou usar quaisquer caracteres que exijam sequências de escape. Literais de string bruta eliminam 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. Uma literal de cadeia de caracteres bruta :

  • Começa e termina com uma sequência de pelo menos três aspas duplas ("""). Você pode usar mais de três caracteres consecutivos para iniciar e terminar a sequência para oferecer suporte a literais de cadeia de caracteres que contenham três (ou mais) caracteres de aspas repetidas.
  • Os literais de cadeias de caracteres brutos de linha única requerem que os caracteres de aspas de abertura e fecho estejam na mesma linha.
  • Literais de cadeia de caracteres brutos de várias linhas exigem caracteres de aspas de abertura e fechamento em sua própria linha.
  • 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 de cadeia de caracteres bruto.
  • Em strings literais brutas de várias linhas, o espaço em branco após as aspas de abertura na mesma linha é ignorado.
  • Em literais de cadeia de caracteres brutos de várias linhas, somente linhas de espaço em branco após a citação de abertura são incluídas no literal de cadeia de caracteres.

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 brutos de várias linhas exigem a sequência de aspas de abertura e fechamento em sua própria linha. O terceiro exemplo é inválido porque o texto está destacado da sequência de aspas de fechamento.

Você deve considerar literais de cadeia de caracteres brutos 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 literais. Literais de cadeia de caracteres brutos são mais fáceis para você e outras pessoas lerem porque se assemelham mais ao 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 fuga Nome do personagem Codificação Unicode
\' Citação única 0x0027
\" Citação dupla 0x0022
\\ Barra invertida 0x005C
\0 Nulo 0x0000
\a Alerta 0x0007
\b Tecla de Retrocesso 0x0008
\e Fuja 0x001B
\f Avanço de formulário 0x000C
\n Nova linha 0x000A
\r Retorno de carro 0x000D
\t Tabulação horizontal 0x0009
\v Tabulação 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 = "ç")

Advertência

Ao utilizar a sequência de escape \x e especificar menos de 4 dígitos hexadecimais, se os caracteres que se seguem imediatamente à sequência de escape forem dígitos hexadecimais válidos (ou seja, 0-9, A-F e a-f), serão interpretados como fazendo 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", então 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 4 dígitos hexadecimais (por exemplo, \x00A1) evita qualquer possível má interpretação.

Observação

Em tempo de compilação, strings literais e raw são convertidas em strings comuns com todas as mesmas sequências de escape. Portanto, se você visualizar uma string literal ou raw na janela de observação do depurador, verá os caracteres de escape que foram adicionados pelo compilador, não a versão literal ou raw do seu código-fonte. Por exemplo, a string literal @"C:\files.txt" aparecerá na janela de observaçã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. As cadeias de formato são criadas incorporando expressões interpoladas ou espaços reservados dentro de chaves. Tudo dentro das chaves ({...}) é resolvido para um valor e apresentado como uma string formatada em tempo de execução. Há dois métodos para criar cadeias de caracteres de formato: interpolação de cadeia de caracteres e formatação composta.

Interpolação de cordas

Você declara cadeias de caracteres interpoladas com o caractere especial $. Uma sequência de caracteres interpolada inclui expressões interpoladas entre chavetas. Se você é novo na interpolação de cadeia de caracteres, consulte o tutorial interativo Interpolação de cadeia de caracteres - 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 seu código. A interpolação de cadeias de caracteres alcança os mesmos resultados que o método String.Format, mas melhora a facilidade de uso e a clareza em linha.

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, é possível usar conjuntamente literais de cadeia bruta com interpolações de cadeia de caracteres. Inicias e terminas a string de formato com três ou mais aspas duplas sucessivas. Se a cadeia de caracteres de saída deve conter o caractere { ou }, você pode usar caracteres $ extras para especificar quantos { e } caracteres iniciar e terminar uma interpolação. Qualquer sequência de menos de { ou } caracteres é incluída na saída. O exemplo seguinte mostra como pode usar essa funcionalidade para mostrar a distância de um ponto da origem e posicionar o ponto entre chavetas:

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 de strings verbatim

O C# também permite a interpolação literal de cadeias de caracteres, por exemplo, em várias linhas, usando a sintaxe $@ ou @$.

Para interpretar as sequências de escape literalmente, use um literal de cadeia de caracteres. Uma cadeia de caracteres literal interpolada começa com o caractere $ seguido pelo caractere @. Você pode usar os tokens $ e @ em qualquer ordem: tanto $@"..." quanto @$"..." são strings literais 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 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 mais informações sobre a formatação de tipos .NET, consulte Formatar Tipos em .NET.

Substrings

Uma substring é qualquer sequência de caracteres contida em uma cadeia de caracteres. Use o método Substring para criar uma nova cadeia de caracteres a partir de uma parte da cadeia de caracteres original. Você pode pesquisar uma ou mais ocorrências de uma substring usando o método IndexOf. Use o método Replace para substituir todas as ocorrências de uma substring especificada por uma nova string. 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 ter acesso apenas de leitura a caracteres individuais, como no exemplo a seguir:

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 que deve ter para modificar caracteres individuais numa string, pode usar um objeto StringBuilder para modificar os caracteres individuais diretamente e, em seguida, criar uma nova string 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, em seguida, 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 ocorrê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 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 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 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);

Usando o StringBuilder para 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 significativamente o desempenho. No entanto, em alguns cenários, como loops apertados que são executados muitas 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 cadeia de caracteres StringBuilder também permite reatribuir caracteres individuais, algo que o tipo de dados de cadeia de caracteres interno 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 a partir 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

Strings, 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 confusão 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 expressões de consulta LINQ em cadeias de caracteres. Para obter mais informações, consulte LINQ and Strings.