Une string en C# est une suite de caractères UTF-16 (des valeurs char). C'est un type référence, mais elle se comporte comme une valeur sur les points qui comptent : elle est immuable, et == compare le texte plutôt que l'identité de l'objet. string est le mot-clé C# du type .NET System.String ; les deux sont interchangeables.
Sortie :
Porto
5
0
*****
hi
Porto has 5 letters
Les chaînes sont immuables
Aucune méthode ne modifie une chaîne sur place. ToUpper, Replace, Trim et toutes les autres méthodes renvoient une nouvelle chaîne et laissent l'originale intacte. Oublier d'utiliser la valeur renvoyée est un bug très courant avec les chaînes :
Sortie :
[ maya ]
[MAYA]
tea
tea and cake
L'immuabilité rend les chaînes sûres à partager entre threads et à utiliser comme clés de dictionnaire. Le coût est que construire une chaîne morceau par morceau dans une boucle crée une nouvelle chaîne à chaque étape ; pour cela, utilisez StringBuilder.
Longueur et indexation
Length est une propriété (sans parenthèses). L'indexeur s[i] renvoie le char à la position i, en comptant à partir de 0, et il est en lecture seule :
Sortie :
7
A
1
IndexOutOfRangeException
XB-2931
C# 8 et plus acceptent aussi un index depuis la fin : code[^1] est le dernier caractère, comme code[code.Length - 1]. Pour prendre plusieurs caractères à la fois, voir substring.
Length compte des unités de code UTF-16, pas ce qu'un lecteur voit comme des caractères. La plupart des lettres de la plupart des langues occupent une unité, mais les emoji et quelques écritures rares en utilisent deux (une paire de substitution), donc "👍".Length vaut 2.
Comparer des chaînes
== et != comparent les caractères, en tenant compte de la casse. Pour tout le reste, passez une valeur StringComparison qui indique comment comparer :
Sortie :
False
False
True
True
apple first
True
False
False
True
Quelle comparaison utiliser :
Ordinalcompare les codes numériques des caractères. C'est rapide, prévisible et identique sur chaque machine. Utilisez-la pour les identifiants, les noms de fichiers, les clés, les valeurs de protocole et tout ce qui n'est pas montré à une personne.OrdinalIgnoreCasefait la même chose en ignorant la casse. C'est le bon choix pour les tests insensibles à la casse, comme les extensions de fichiers ou les en-têtes HTTP.CurrentCulture(etCurrentCultureIgnoreCase) suit les règles de la langue de l'utilisateur, donc trie les mots comme le ferait un dictionnaire dans cette langue. Utilisez-la pour trier des listes affichées aux utilisateurs.InvariantCultureapplique des règles culturelles qui ne dépendent pas des paramètres de langue de l'utilisateur. Elle dépend quand même de la bibliothèque de globalisation : le .NET moderne utilise ICU, .NET Framework utilise NLS de Windows, et les deux peuvent ordonner certaines chaînes différemment.
string.Compare(a, b) et a.CompareTo(b) sans StringComparison utilisent la culture courante, si bien que leurs résultats varient d'une machine à l'autre. Évitez de comparer avec a.ToLower() == b.ToLower() : cela alloue deux nouvelles chaînes et donne de mauvaises réponses dans certaines cultures (le i avec et sans point du turc est le cas classique).
Appeler a.Equals(b) quand a vaut null lève une NullReferenceException, alors que a == b et la méthode statique string.Equals(a, b) gèrent null sans problème.
Caractères d'échappement
Dans un littéral de chaîne ordinaire, une barre oblique inverse commence une séquence d'échappement :
| Échappement | Signification |
|---|---|
\n | Nouvelle ligne (saut de ligne) |
\r | Retour chariot |
\t | Tabulation |
\\ | Barre oblique inverse |
\" | Guillemet double |
\' | Apostrophe (nécessaire seulement dans un littéral char) |
\0 | Caractère nul |
\uXXXX | Caractère UTF-16 par code hexadécimal à 4 chiffres, par exemple \u00e9 |
\U0001F44D | Caractère par code hexadécimal à 8 chiffres ; au-delà de U+FFFF il devient deux valeurs char |
\xH à \xHHHH | Caractère par 1 à 4 chiffres hexadécimaux (à éviter : la longueur est ambiguë) |
\a, \b, \f, \v | Alerte, retour arrière, saut de page, tabulation verticale |
\e | Caractère d'échappement, U+001B (C# 13) |
Sortie :
Name: Ana
City: Porto
She said "hi"
C:\temp\report.txt
cafe = cafe
' is a quote char
Une séquence non reconnue comme "\d" est une erreur de compilation (CS1009, unrecognized escape sequence) ; c'est ce qui arrive quand un chemin Windows ou une expression régulière est écrit comme une chaîne ordinaire.
Chaînes verbatim et chaînes multilignes
Préfixer un littéral par @ le rend verbatim : les barres obliques inverses sont des caractères littéraux, et la chaîne peut s'étendre sur plusieurs lignes. Le seul échappement restant est "", qui produit un guillemet double.
Sortie :
C:\Users\ana\Documents\notes.txt
\d{3}-\d{4}
He said "ready" and left.
Rua das Flores 12
4050-262 Porto
Portugal
first line
second line
Une chaîne verbatim multiligne inclut tout ce qui se trouve entre les guillemets, y compris l'indentation des lignes suivantes, c'est pourquoi on les écrit en général collées à la marge comme ci-dessus. Les sauts de ligne qu'elle contient sont ceux du fichier source, donc un fichier enregistré avec des fins de ligne Windows produit \r\n.
C# 11 a ajouté les littéraux de chaîne bruts (raw string literals), qui résolvent ces deux problèmes. Ils commencent et se terminent par trois guillemets doubles ou plus, n'ont besoin d'aucun échappement et retirent l'indentation correspondant à celle des guillemets fermants :
// C# 11 and later
string json = """
{
"name": "Ana",
"path": "C:\temp"
}
""";
// The 4 spaces before the closing """ are removed from every line.
Si le contenu lui-même contient """, commencez et terminez par quatre guillemets. Les littéraux bruts se combinent aussi avec l'interpolation ($"""...""") ; voir interpolation de chaînes.
Null, vide et espaces
Une variable string peut valoir null (aucune chaîne), être vide ("", longueur 0) ou ne contenir que des espaces. Deux méthodes statiques vérifient ces cas sans risquer de NullReferenceException :
Sortie :
null empty: True blank: True
"" empty: True blank: True
" " empty: False blank: True
"Ana" empty: False blank: False
True
Pour valider une saisie utilisateur, string.IsNullOrWhiteSpace est presque toujours celle qu'il vous faut. string.Empty et "" sont la même valeur ; lequel écrire est une question de style.
Parcourir les caractères
Une chaîne est énumérable, donc foreach visite chaque char. Le type char possède des méthodes statiques pour classer les caractères :
Sortie :
letters=6 digits=4 upper=1 symbols=1
!6202tesnuS
Assembler des chaînes
+ concatène, et fonctionne avec n'importe quel type de l'autre côté (il appelle ToString()). Pour combiner beaucoup de valeurs, préférez l'interpolation ou string.Join :
Sortie :
Ana Silva, 31
Ana Silva, 31
AnaSilva
tea | coffee | juice
Total: 23
Total: 5
Les deux dernières lignes montrent un piège de priorité : + est évalué de gauche à droite, donc dès que la partie gauche est une chaîne, chaque + suivant est une concaténation. Mettez l'arithmétique entre parenthèses dans une concaténation.
Questions fréquentes
Comment obtenir la longueur d'une chaîne en C# ?
Utilisez la propriété Length : "hello".Length vaut 5. C'est une propriété, pas une méthode, donc sans parenthèses. Length compte des unités de code UTF-16, si bien qu'un emoji ou un autre caractère hors du plan multilingue de base compte pour 2. L'appeler sur une chaîne null lève une NullReferenceException.
Comment comparer des chaînes en C# ?
a == b compare le texte en tenant compte de la casse. Pour une égalité insensible à la casse, utilisez string.Equals(a, b, StringComparison.OrdinalIgnoreCase). Pour trier ou ordonner des chaînes, utilisez string.Compare(a, b, StringComparison.Ordinal) ou une comparaison sensible à la culture, qui renvoie un nombre négatif, zéro ou un nombre positif.
Comment écrire une chaîne multiligne en C# ?
Préfixez le littéral par @ pour le rendre verbatim : il peut s'étendre sur plusieurs lignes, les barres obliques inverses sont littérales et un guillemet double s'écrit "". Depuis C# 11, les littéraux de chaîne bruts délimités par """ s'étendent aussi sur plusieurs lignes, retirent l'indentation commune et ne demandent aucun échappement. Vous pouvez aussi assembler des lignes avec \n ou Environment.NewLine.
Qu'est-ce qu'une chaîne verbatim en C# ?
Un littéral de chaîne préfixé par @, comme @"C:\Users\ana". Les séquences d'échappement ne sont pas interprétées, une barre oblique inverse reste donc une barre oblique inverse, ce qui en fait le choix naturel pour les chemins Windows et les expressions régulières. Le seul échappement possible à l'intérieur est "" pour un guillemet double.
Quelle est la différence entre string et String en C# ?
Aucune. string est l'alias en mot-clé C# du type .NET System.String, tout comme int est un alias de System.Int32. La convention est d'utiliser string pour les déclarations et string.IsNullOrEmpty(...) pour les appels statiques, mais les deux compilent exactement vers la même chose.
Quels caractères d'échappement C# prend-il en charge ?
\n saut de ligne, \r retour chariot, \t tabulation, \\ barre oblique inverse, \" guillemet double, \' apostrophe, \0 caractère nul, \uXXXX un caractère UTF-16 par son code hexadécimal, \U0001F600 un caractère par un code à 8 chiffres (il devient une paire de substitution), \a alerte, \b retour arrière, \f saut de page, \v tabulation verticale, et \e (C# 13) échappement. Une séquence inconnue comme \d est une erreur de compilation (CS1009), c'est pourquoi les expressions régulières s'écrivent en général sous forme de chaînes verbatim.