Partager via


Chaînes et littéraux de chaîne

Une chaîne est un objet de type String dont la valeur est du texte. En interne, le texte est stocké sous la forme d’une collection séquentielle en lecture seule d’objets Char. La propriété Length d’une chaîne représente le nombre d’objets Char qu’il contient, et non le nombre de caractères Unicode. Pour accéder aux points de code Unicode individuels dans une chaîne, utilisez l’objet StringInfo.

string vs. System.String

En C#, le mot clé string est un alias pour String; par conséquent, String et string sont équivalents. Utilisez l’alias fourni string car il fonctionne même sans using System;. La classe String fournit de nombreuses méthodes pour créer, manipuler et comparer des chaînes en toute sécurité. En outre, le langage C# surcharge certains opérateurs pour simplifier les opérations de chaîne courantes. Pour plus d'informations sur le mot clé, consultez string. Pour plus d’informations sur le type et ses méthodes, consultez String.

Déclaration et initialisation de chaînes

Vous pouvez déclarer et initialiser des chaînes de différentes façons, comme illustré dans l’exemple suivant :

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

Vous n’utilisez pas l’opérateur nouvelle pour créer un objet de chaîne, sauf lors de l’initialisation de la chaîne avec un tableau de caractères.

Initialisez une chaîne avec la valeur constante Empty pour créer un objet String dont la chaîne est de longueur nulle. La représentation de littéral de chaîne d’une chaîne de longueur nulle est "". En initialisant des chaînes avec la valeur Empty au lieu de null, vous pouvez réduire les chances d’un NullReferenceException se produisant. Utilisez la méthode de IsNullOrEmpty(String) statique pour vérifier la valeur d’une chaîne avant de tenter de l’accéder.

Immuabilité des chaînes

Les objets de chaîne sont immuables : ils ne peuvent pas être modifiés après leur création. Toutes les méthodes String et les opérateurs C# qui semblent modifier une chaîne retournent réellement les résultats dans un nouvel objet de chaîne. Dans l’exemple suivant, lorsque le contenu de s1 et s2 sont concaténés pour former une seule chaîne, les deux chaînes d’origine ne sont pas modifiées. L’opérateur += crée une chaîne qui contient le contenu combiné. Ce nouvel objet est affecté à la variable s1, et l’objet d’origine affecté à s1 est libéré pour le garbage collection, car aucune autre variable ne contient de référence à celle-ci.

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.

Étant donné qu'une "modification" de chaîne est en fait la création d'une nouvelle chaîne, vous devez faire preuve de prudence lorsque vous créez des références à des chaînes. Si vous créez une référence à une chaîne, puis « modifiez » la chaîne d’origine, la référence continue de pointer vers l’objet d’origine au lieu du nouvel objet créé lors de la modification de la chaîne. Le code suivant illustre ce comportement :

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

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

Pour plus d’informations sur la création de chaînes basées sur des modifications telles que les opérations de recherche et de remplacement sur la chaîne d’origine, consultez Comment modifier le contenu de chaîne.

Littéraux de chaîne entre guillemets

Les littéraux de chaîne entre guillemets commencent et se terminent par un seul caractère de guillemet double (") sur la même ligne. Les littéraux de chaîne entre guillemets conviennent mieux aux chaînes qui s’ajustent sur une seule ligne et n’incluent aucune séquence d’échappement. Un littéral de chaîne entre guillemets doit incorporer des caractères d’échappement, comme illustré dans l’exemple suivant :

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

Littéraux de chaîne textuelle

Les littéraux de chaîne verbatim sont plus pratiques pour les chaînes multilignes, les chaînes qui contiennent des caractères de barre oblique inverse ou des guillemets doubles incorporés. Les chaînes textuelles conservent les nouveaux caractères de ligne dans le texte de chaîne. Utilisez des guillemets doubles pour incorporer un guillemet à l’intérieur d’une chaîne textuelle littérale. L’exemple suivant montre certaines utilisations courantes des chaînes textuelles :

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."

Littéraux de chaîne bruts

À partir de C# 11, vous pouvez utiliser des littéraux de chaîne brute pour créer plus facilement des chaînes multilignes ou utiliser des caractères nécessitant des séquences d’échappement. Les littéraux de chaîne brutes suppriment la nécessité d’utiliser des séquences d’échappement. Vous pouvez écrire la chaîne, y compris la mise en forme d’espace blanc, la façon dont vous souhaitez qu’elle apparaisse dans la sortie. Littéral de chaîne brute :

  • Commence et se termine par une séquence d’au moins trois guillemets doubles ("""). Vous pouvez utiliser plus de trois caractères consécutifs pour démarrer et terminer la séquence afin de gérer les littéraux de chaîne qui contiennent trois caractères de guillemets répétés ou plus.
  • Les littéraux de chaîne brute à une seule ligne nécessitent les guillemets d’ouverture et de fermeture sur la même ligne.
  • Les littéraux de chaîne brute multilignes nécessitent des guillemets ouvrants et fermants sur leur propre ligne.
  • Dans les littéraux de chaîne brute à plusieurs lignes, tous les espaces blancs à gauche des guillemets fermants sont supprimés de toutes les lignes du littéral de chaîne brut.
  • Dans les littéraux de chaîne brute multilignes, les espaces blancs qui suivent le guillemet ouvrant sur la même ligne sont ignorés.
  • Dans les littéraux de chaîne brute multilignes, les lignes contenant uniquement des espaces blancs qui suivent le guillemet ouvrant sont incluses dans le littéral de chaîne.

Les exemples suivants illustrent ces règles :

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: """
    """";

Les exemples suivants illustrent les erreurs du compilateur signalées en fonction de ces règles :

// 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.
    """;

Les deux premiers exemples ne sont pas valides, car les littéraux de chaîne brute multiligne nécessitent la séquence de guillemets d’ouverture et de fermeture sur sa propre ligne. Le troisième exemple n’est pas valide, car le texte est décalé par rapport à la séquence de guillemets fermants.

Vous devez prendre en compte les littéraux de chaîne brute lorsque vous générez du texte qui comprend des caractères qui nécessitent des séquences d’échappement lors de l’utilisation de littéraux de chaîne entre guillemets ou de littéraux de chaînes verbatim. Les littéraux de chaîne brute sont plus faciles à lire pour vous et d’autres personnes, car ils ressemblent plus étroitement au texte de sortie. Par exemple, considérez le code suivant qui inclut une chaîne de JSON mis en forme :

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"
  ]
}
""";

Séquences d’échappement de chaîne

Séquence d’échappement Nom du personnage Codage Unicode
\' Guillemet simple 0x0027
\" Guillemet double 0x0022
\\ Barre oblique inverse 0x005C
\0 Zéro 0x0000
\a Alerte 0x0007
\b Retour arrière 0x0008
\e Échapper 0x001B
\f Flux de formulaire 0x000C
\n Nouvelle ligne 0x000A
\r Retour chariot 0x000D
\t Tabulation horizontale 0x0009
\v Tabulation verticale 0x000B
\u Séquence d’échappement Unicode (UTF-16) \uHHHH (plage : 0000-FFFF ; exemple : \u00E7 = « ç »)
\U Séquence d’échappement Unicode (UTF-32) \U00HHHHHH (plage : 000000 - 10FFFF ; exemple : \U0001F47D = «  »)
\x Séquence d’échappement Unicode similaire à « \u », sauf avec une longueur variable \xH[H][H][H] (plage : 0 - FFFF ; exemple : \x00E7 ou \x0E7 ou \xE7 = « ç »)

Avertissement

Lors de l’utilisation de la séquence d’échappement \x et en spécifiant moins de 4 chiffres hexadécimaux, si les caractères qui suivent immédiatement la séquence d’échappement sont des chiffres hexadécimaux valides (c’est-à-dire 0-9, A-F et a-f), ils sont interprétés comme faisant partie de la séquence d’échappement. Par exemple, \xA1 produit « ¡ », qui est le point de code U+00A1. Toutefois, si le caractère suivant est « A » ou « a », la séquence d’échappement sera interprétée comme étant \xA1A et produit « ਚ », qui est le point de code U+0A1A. Dans ce cas, la spécification de tous les 4 chiffres hexadécimaux (par exemple, \x00A1) empêche toute mauvaise interprétation possible.

Remarque

Au moment de la compilation, les chaînes détaillées et brutes sont converties en chaînes ordinaires avec toutes les mêmes séquences d’échappement. Par conséquent, si vous affichez une chaîne textuelle ou brute dans la fenêtre Espion du débogueur, vous verrez les caractères d’échappement qui ont été ajoutés par le compilateur et non la version textuelle ou brute de votre code source. Par exemple, la chaîne textuelle @"C:\files.txt" s’affiche dans la fenêtre Espion en tant que "C:\\files.txt".

Chaînes de format

Une chaîne de format est une chaîne dont le contenu est déterminé dynamiquement au moment de l’exécution. Les chaînes de format sont créées en incorporant des expressions interpolées ou des espaces réservés à l’intérieur d’accolades dans une chaîne. Tout ce qui se trouve à l’intérieur des accolades ({...}) est résolu en une valeur et sortie sous forme de chaîne mise en forme au moment du runtime. Il existe deux méthodes pour créer des chaînes de format : l’interpolation de chaîne et la mise en forme composite.

Interpolation de chaîne

Vous déclarez chaînes interpolées avec le caractère spécial $. Une chaîne interpolée inclut des expressions interpolées dans des accolades. Si vous débutez avec l’interpolation de chaîne, consultez le didacticiel interactif - Didacticiel interactif C# pour obtenir une vue d’ensemble rapide.

Utilisez l’interpolation de chaîne pour améliorer la lisibilité et la maintenance de votre code. L’interpolation de chaîne obtient les mêmes résultats que la méthode String.Format, mais améliore la facilité d’utilisation et la clarté inline.

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.

Vous pouvez utiliser l’interpolation de chaîne pour initialiser une chaîne constante lorsque toutes les expressions utilisées pour les espaces réservés sont également des chaînes constantes.

À partir de C# 11, vous pouvez combiner des littéraux de chaîne brute avec des interpolations de chaîne. Vous commencez et terminez la chaîne de format avec trois guillemets doubles successifs ou plus. Si votre chaîne de sortie doit contenir le caractère { ou }, vous pouvez utiliser des caractères $ supplémentaires pour spécifier le nombre de caractères { et } caractères de début et de fin d’une interpolation. Toute séquence de caractères comprenant moins de { ou } est incluse dans la sortie. L’exemple suivant montre comment utiliser cette fonctionnalité pour afficher la distance d’un point par rapport à l'origine, et placer le point entre accolades :

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.

Interpolation littérale de chaîne

C# autorise également l'interpolation de chaînes mot à mot, par exemple sur plusieurs lignes, en utilisant la syntaxe $@ ou @$.

Pour interpréter les séquences d’échappement littéralement, utilisez un littéral de chaîne textuelle. Une chaîne verbatim interpolée commence par le caractère $ suivi du caractère @. Vous pouvez utiliser les jetons $ et @ dans n'importe quel ordre : les $@"..." et les @$"..." sont des chaînes littérales interpolées valides.

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.

Mise en forme composite

String.Format utilise des espaces réservés entre accolades pour créer une chaîne de format. Cet exemple génère une sortie similaire à la méthode d’interpolation de chaîne utilisée dans l’exemple précédent.

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.

Pour plus d’informations sur la mise en forme des types .NET, consultez Types de mise en forme dans .NET.

Sous-chaînes

Une sous-chaîne est une séquence de caractères contenue dans une chaîne. Utilisez la méthode Substring pour créer une chaîne à partir d’une partie de la chaîne d’origine. Vous pouvez rechercher une ou plusieurs occurrences d’une sous-chaîne à l’aide de la méthode IndexOf. Utilisez la méthode Replace pour remplacer toutes les occurrences d’une sous-chaîne spécifiée par une nouvelle chaîne. Comme la méthode Substring, Replace retourne réellement une nouvelle chaîne et ne modifie pas la chaîne d’origine. Pour plus d’informations, consultez Comment rechercher des chaînes et Comment modifier le contenu des chaînes.

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

Accès aux caractères individuels

Vous pouvez utiliser la notation de tableau avec une valeur d’index pour acquérir un accès en lecture seule à des caractères individuels, comme dans l’exemple suivant :

string s5 = "Printing backwards";

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

Si les méthodes String ne fournissent pas les fonctionnalités dont vous devez avoir besoin pour modifier des caractères individuels dans une chaîne, vous pouvez utiliser un objet StringBuilder pour modifier les caractères individuels « sur place », puis créer une chaîne pour stocker les résultats à l’aide des méthodes StringBuilder. Dans l’exemple suivant, supposons que vous devez modifier la chaîne d’origine d’une manière particulière, puis stocker les résultats pour une utilisation ultérieure :

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?

Chaînes Null et chaînes vides

Une chaîne vide est une instance d’un objet System.String qui contient zéro caractère. Les chaînes vides sont souvent utilisées dans différents scénarios de programmation pour représenter un champ de texte vide. Vous pouvez appeler des méthodes sur des chaînes vides, car ce sont des objets System.String valides. Les chaînes vides sont initialisées comme suit :

string s = String.Empty;

En revanche, une chaîne Null ne fait pas référence à une instance d’un objet System.String et toute tentative d’appel d’une méthode sur une chaîne Null provoque une NullReferenceException. Toutefois, vous pouvez utiliser des chaînes Null dans les opérations de concaténation et de comparaison avec d’autres chaînes. Les exemples suivants illustrent certains cas dans lesquels une référence à une chaîne null peut ou ne peut pas entraîner la levée d'une exception :

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

Utilisation de StringBuilder pour la création rapide de chaînes

Les opérations de chaîne dans .NET sont hautement optimisées et, dans la plupart des cas, n’ont pas d’impact significatif sur les performances. Toutefois, dans certains scénarios, notamment dans le cas de boucles serrées qui s’exécutent plusieurs centaines voire milliers de fois, les opérations String peuvent affecter les performances. La classe StringBuilder crée une mémoire tampon de chaîne qui offre de meilleures performances si votre programme effectue de nombreuses manipulations de chaînes. La chaîne StringBuilder vous permet également de réassigner des caractères individuels, une fonctionnalité non prise en charge par les types de données string intégrés. Ce code, par exemple, modifie le contenu d’une chaîne sans créer de nouvelle chaîne :

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

Dans cet exemple, un objet StringBuilder est utilisé pour créer une chaîne à partir d’un ensemble de types numériques :

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

Chaînes, méthodes d’extension et LINQ

Étant donné que le type String implémente IEnumerable<T>, vous pouvez utiliser les méthodes d’extension définies dans la classe Enumerable sur des chaînes. Pour éviter l’encombrement visuel, ces méthodes sont exclues d’IntelliSense pour le type de String, mais elles sont néanmoins disponibles. Vous pouvez également utiliser des expressions de requête LINQ sur des chaînes. Pour plus d’informations, consultez LINQ and Strings.