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. Il n’existe aucun caractère Null à la fin d’une chaîne C# ; par conséquent, une chaîne C# peut contenir n’importe quel nombre de caractères Null incorporés (’\0’). La propriété Length d’une chaîne représente le nombre d’objets Char qu’elle contient, et non pas le nombre de caractères Unicode. Pour accéder à des points de code Unicode individuels dans une chaîne, utilisez l’objet StringInfo.

chaîne vs. System.String

En C#, le mot clé string est un alias pour String. Par conséquent, String et string sont équivalents, même s’il est recommandé d’utiliser l’alias string fourni 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înes courantes. Pour plus d’informations sur le mot clé, voir chaîne. 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 manières, 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 new pour créer un objet de chaîne, excepté lors de l’initialisation de la chaîne avec un tableau de chars.

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 les chaînes avec la valeur Empty au lieu de null, vous pouvez réduire les risques de levée de l’exception NullReferenceException. Utilisez la méthode statique IsNullOrEmpty(String) pour vérifier la valeur d’une chaîne avant de tenter d’y accéder.

Immuabilité des chaînes

Les objets de chaîne sont immuables : une fois créés, ils ne peuvent pas être modifiés. Toutes les méthodes String et tous les opérateurs C# qui semblent modifier une chaîne retournent en fait les résultats dans un nouvel objet string. Dans l’exemple suivant, lorsque les contenus de s1 et s2 sont concaténés pour former une chaîne unique, les deux chaînes d’origine restent inchangées. L’opérateur += crée une nouvelle chaîne qui contient le contenu combiné. Ce nouvel objet est assigné à la variable s1 et l’objet d’origine qui a été assigné à s1 est libéré pour la garbage collection, car aucune autre variable ne le référence.

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 correspond en fait à la création d’une nouvelle chaîne, vous devez être prudent lorsque vous créez des références aux 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 à 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 nouvelles chaînes basées sur des modifications telles que les opérations rechercher-remplacer sur la chaîne d’origine, voir Comment modifier du 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 simple 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 des guillemets dans une chaîne textuelle. L’exemple suivant montre certaines utilisations courantes des chaînes textuelles :

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 des espaces blancs, de 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 commencer et terminer la séquence avec plus de trois caractères consécutifs afin de prendre en charge les littéraux de chaîne qui contiennent trois (ou plus) guillemets répétés.
  • 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, tout espace blanc à gauche des guillemets fermants est supprimé.

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 sorti de 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 seront plus faciles à lire pour vous et d’autres personnes, car ils ressembleront plus étroitement au texte de sortie. Par exemple, considérez le code suivant qui inclut une chaîne de JSON mise 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"
  ]
}
""";

Comparez ce texte avec le texte équivalent de notre exemple sur la sérialisation JSON, qui n’utilise pas cette nouvelle fonctionnalité.

Séquences d’échappement de chaîne

Séquence d'échappement Nom du caractère Codage Unicode
\' Guillemet simple 0x0027
\" Guillemet double 0x0022
\\ Barre oblique inverse 0x005C
\0 Null 0x0000
\a Alerte 0x0007
\b Retour arrière 0x0008
\f Saut de page 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", mais avec une longueur variable \xH[H][H][H] (plage : 0-FFFF ; exemple : \x00E7 ou \x0E7 ou \xE7 = « ç »)

Avertissement

Quand vous utilisez la séquence d’échappement \x et spécifiez 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 (par ex. 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 est interprétée comme étant \xA1A et génère « ਚ », qui correspond au point de code U+0A1A. Dans ce cas, la spécification des 4 chiffres hexadécimaux (par ex. \x00A1) empêche toute mauvaise interprétation possible.

Notes

Au moment de la compilation, les chaînes textuelles sont converties en chaînes normales avec les mêmes séquences d’échappement. Par conséquent, si vous affichez une chaîne textuelle 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 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é de manière dynamique au moment du runtime. 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 ({...}) sera 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

Disponible dans C# 6.0 et versions ultérieures, les chaînes interpolées sont identifiées par le caractère spéciale $ et incluent des expressions interpolées entre accolades. Si vous ne connaissez pas l’interpolation de chaîne, consultez le tutoriel interactif Interpolation de chaînes en C# pour obtenir une vue d’ensemble.

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

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.

À partir de C# 10, 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 par au moins trois guillemets doubles successifs. 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 } de début de fin d’une interpolation. Toute séquence de moins de caractères { ou } de caractères 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 à l’intérieur des 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.

Mise en forme composite

String.Format utilise des espaces réservés entre accolades pour créer une chaîne de format. Cet exemple renvoie une sortie similaire à la méthode d’interpolation de chaîne utilisée ci-dessus.

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 Mise en forme des types dans .NET.

Sous-chaînes

Une sous-chaîne est une séquence de caractères qui est 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 en utilisant 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 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 du contenu de chaîne.

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 obtenir un accès en lecture seule aux 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 la fonctionnalité nécessaire pour modifier les caractères individuels d’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 en utilisant les méthodes StringBuilder. Dans l’exemple suivant, supposons que vous devez modifier la chaîne d’origine d’une façon 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 divers 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. 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 pour appeler une méthode sur une chaîne Null lève une exception NullReferenceException. Toutefois, vous pouvez utiliser des chaînes Null dans les opérations de comparaison et de concaténation avec d’autres chaînes. Les exemples suivants illustrent certains cas dans lesquels une référence à une chaîne Null provoque ou non 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 créer rapidement une chaîne

Les opérations Strings dans .NET sont hautement optimisées et, dans la plupart des cas, n’ont pas d’incidence significative 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 un tampon de chaîne qui offre de meilleures performances si votre programme exécute 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 une surcharge visuelle, ces méthodes sont exclues d’IntelliSense pour le type String, mais elles restent néanmoins disponibles. Vous pouvez également utiliser des expressions de requête LINQ sur des chaînes. Pour plus d’informations, consultez LINQ et Strings.