System.Char struct
Cet article vous offre des remarques complémentaires à la documentation de référence pour cette API.
La Char structure représente des points de code Unicode à l’aide de l’encodage UTF-16. La valeur d’un Char objet est sa valeur numérique 16 bits (ordinal).
Si vous n’êtes pas familiarisé avec Unicode, les valeurs scalaires, les points de code, les paires de substitution, UTF-16 et le type, consultez Présentation de l’encodage Rune de caractères dans .NET.
Cet article examine la relation entre un Char objet et un caractère et décrit certaines tâches courantes effectuées avec Char des instances. Nous vous recommandons de considérer le Rune type, introduit dans .NET Core 3.0, comme alternative à Char l’exécution de certaines de ces tâches.
Objets Char, caractères Unicode et chaînes
Un String objet est une collection séquentielle de Char structures qui représente une chaîne de texte. La plupart des caractères Unicode peuvent être représentés par un objet unique Char , mais un caractère encodé en tant que caractère de base, paire de substitution et/ou séquence de caractères combinant est représenté par plusieurs Char objets. Pour cette raison, une Char structure dans un String objet n’est pas nécessairement équivalente à un caractère Unicode unique.
Plusieurs unités de code 16 bits sont utilisées pour représenter des caractères Unicode uniques dans les cas suivants :
Glyphes, qui peuvent être constitués d’un caractère unique ou d’un caractère de base suivi d’un ou plusieurs caractères combinés. Par exemple, le caractère ä est représenté par un Char objet dont l’unité de code est U+0061 suivie d’un Char objet dont l’unité de code est U+0308. (Le caractère ä peut également être défini par un seul Char objet qui a une unité de code de U+00E4.) L’exemple suivant illustre que le caractère ä se compose de deux Char objets.
using System; using System.IO; public class Example1 { public static void Main() { StreamWriter sw = new StreamWriter("chars1.txt"); char[] chars = { '\u0061', '\u0308' }; string strng = new String(chars); sw.WriteLine(strng); sw.Close(); } } // The example produces the following output: // ä
open System open System.IO let sw = new StreamWriter("chars1.txt") let chars = [| '\u0061'; '\u0308' |] let string = String chars sw.WriteLine string sw.Close() // The example produces the following output: // ä
Imports System.IO Module Example2 Public Sub Main() Dim sw As New StreamWriter("chars1.txt") Dim chars() As Char = {ChrW(&H61), ChrW(&H308)} Dim strng As New String(chars) sw.WriteLine(strng) sw.Close() End Sub End Module ' The example produces the following output: ' ä
Caractères en dehors du plan multilingue unicode de base (BMP). Unicode prend en charge seize plans en plus du BMP, qui représente le plan 0. Un point de code Unicode est représenté dans UTF-32 par une valeur 21 bits qui inclut le plan. Par exemple, U+1D160 représente le caractère MUSICAL SY Mo OL HUITIÈME NOTE. Étant donné que l’encodage UTF-16 n’a que 16 bits, les caractères en dehors du BMP sont représentés par des paires de substitution dans UTF-16. L’exemple suivant illustre que l’équivalent UTF-32 de U+1D160, le caractère MUSICAL SY Mo OL HUITIÈME NOTE, est U+D834 U+DD60. U+D834 est le substitut élevé ; Les substitutions élevées vont de U+D800 à U+DBFF. U+DD60 est le substitut faible ; Les substitutions faibles vont de U+DC00 à U+DFFF.
using System; using System.IO; public class Example3 { public static void Main() { StreamWriter sw = new StreamWriter(@".\chars2.txt"); int utf32 = 0x1D160; string surrogate = Char.ConvertFromUtf32(utf32); sw.WriteLine("U+{0:X6} UTF-32 = {1} ({2}) UTF-16", utf32, surrogate, ShowCodePoints(surrogate)); sw.Close(); } private static string ShowCodePoints(string value) { string retval = null; foreach (var ch in value) retval += String.Format("U+{0:X4} ", Convert.ToUInt16(ch)); return retval.Trim(); } } // The example produces the following output: // U+01D160 UTF-32 = ð (U+D834 U+DD60) UTF-16
open System open System.IO let showCodePoints (value: char seq) = let str = value |> Seq.map (fun ch -> $"U+{Convert.ToUInt16 ch:X4}") |> String.concat "" str.Trim() let sw = new StreamWriter(@".\chars2.txt") let utf32 = 0x1D160 let surrogate = Char.ConvertFromUtf32 utf32 sw.WriteLine $"U+{utf32:X6} UTF-32 = {surrogate} ({showCodePoints surrogate}) UTF-16" sw.Close() // The example produces the following output: // U+01D160 UTF-32 = ð (U+D834 U+DD60) UTF-16
Imports System.IO Module Example4 Public Sub Main() Dim sw As New StreamWriter(".\chars2.txt") Dim utf32 As Integer = &H1D160 Dim surrogate As String = Char.ConvertFromUtf32(utf32) sw.WriteLine("U+{0:X6} UTF-32 = {1} ({2}) UTF-16", utf32, surrogate, ShowCodePoints(surrogate)) sw.Close() End Sub Private Function ShowCodePoints(value As String) As String Dim retval As String = Nothing For Each ch In value retval += String.Format("U+{0:X4} ", Convert.ToUInt16(ch)) Next Return retval.Trim() End Function End Module ' The example produces the following output: ' U+01D160 UTF-32 = ð (U+D834 U+DD60) UTF-16
Caractères et catégories de caractères
Chaque caractère Unicode ou paire de substitution valide appartient à une catégorie Unicode. Dans .NET, les catégories Unicode sont représentées par les membres de l’énumération UnicodeCategory et incluent des valeurs telles que UnicodeCategory.CurrencySymbol, UnicodeCategory.LowercaseLetteret UnicodeCategory.SpaceSeparator, par exemple.
Pour déterminer la catégorie Unicode d’un caractère, appelez la GetUnicodeCategory méthode. Par exemple, l’exemple suivant appelle la GetUnicodeCategory catégorie Unicode de chaque caractère dans une chaîne. L’exemple fonctionne correctement uniquement s’il n’existe aucune paire de substitution dans l’instance String .
using System;
using System.Globalization;
class Example
{
public static void Main()
{
// Define a string with a variety of character categories.
String s = "The red car drove down the long, narrow, secluded road.";
// Determine the category of each character.
foreach (var ch in s)
Console.WriteLine("'{0}': {1}", ch, Char.GetUnicodeCategory(ch));
}
}
// The example displays the following output:
// 'T': UppercaseLetter
// 'h': LowercaseLetter
// 'e': LowercaseLetter
// ' ': SpaceSeparator
// 'r': LowercaseLetter
// 'e': LowercaseLetter
// 'd': LowercaseLetter
// ' ': SpaceSeparator
// 'c': LowercaseLetter
// 'a': LowercaseLetter
// 'r': LowercaseLetter
// ' ': SpaceSeparator
// 'd': LowercaseLetter
// 'r': LowercaseLetter
// 'o': LowercaseLetter
// 'v': LowercaseLetter
// 'e': LowercaseLetter
// ' ': SpaceSeparator
// 'd': LowercaseLetter
// 'o': LowercaseLetter
// 'w': LowercaseLetter
// 'n': LowercaseLetter
// ' ': SpaceSeparator
// 't': LowercaseLetter
// 'h': LowercaseLetter
// 'e': LowercaseLetter
// ' ': SpaceSeparator
// 'l': LowercaseLetter
// 'o': LowercaseLetter
// 'n': LowercaseLetter
// 'g': LowercaseLetter
// ',': OtherPunctuation
// ' ': SpaceSeparator
// 'n': LowercaseLetter
// 'a': LowercaseLetter
// 'r': LowercaseLetter
// 'r': LowercaseLetter
// 'o': LowercaseLetter
// 'w': LowercaseLetter
// ',': OtherPunctuation
// ' ': SpaceSeparator
// 's': LowercaseLetter
// 'e': LowercaseLetter
// 'c': LowercaseLetter
// 'l': LowercaseLetter
// 'u': LowercaseLetter
// 'd': LowercaseLetter
// 'e': LowercaseLetter
// 'd': LowercaseLetter
// ' ': SpaceSeparator
// 'r': LowercaseLetter
// 'o': LowercaseLetter
// 'a': LowercaseLetter
// 'd': LowercaseLetter
// '.': OtherPunctuation
open System
// Define a string with a variety of character categories.
let s = "The red car drove down the long, narrow, secluded road."
// Determine the category of each character.
for ch in s do
printfn $"'{ch}': {Char.GetUnicodeCategory ch}"
// The example displays the following output:
// 'T': UppercaseLetter
// 'h': LowercaseLetter
// 'e': LowercaseLetter
// ' ': SpaceSeparator
// 'r': LowercaseLetter
// 'e': LowercaseLetter
// 'd': LowercaseLetter
// ' ': SpaceSeparator
// 'c': LowercaseLetter
// 'a': LowercaseLetter
// 'r': LowercaseLetter
// ' ': SpaceSeparator
// 'd': LowercaseLetter
// 'r': LowercaseLetter
// 'o': LowercaseLetter
// 'v': LowercaseLetter
// 'e': LowercaseLetter
// ' ': SpaceSeparator
// 'd': LowercaseLetter
// 'o': LowercaseLetter
// 'w': LowercaseLetter
// 'n': LowercaseLetter
// ' ': SpaceSeparator
// 't': LowercaseLetter
// 'h': LowercaseLetter
// 'e': LowercaseLetter
// ' ': SpaceSeparator
// 'l': LowercaseLetter
// 'o': LowercaseLetter
// 'n': LowercaseLetter
// 'g': LowercaseLetter
// ',': OtherPunctuation
// ' ': SpaceSeparator
// 'n': LowercaseLetter
// 'a': LowercaseLetter
// 'r': LowercaseLetter
// 'r': LowercaseLetter
// 'o': LowercaseLetter
// 'w': LowercaseLetter
// ',': OtherPunctuation
// ' ': SpaceSeparator
// 's': LowercaseLetter
// 'e': LowercaseLetter
// 'c': LowercaseLetter
// 'l': LowercaseLetter
// 'u': LowercaseLetter
// 'd': LowercaseLetter
// 'e': LowercaseLetter
// 'd': LowercaseLetter
// ' ': SpaceSeparator
// 'r': LowercaseLetter
// 'o': LowercaseLetter
// 'a': LowercaseLetter
// 'd': LowercaseLetter
// '.': OtherPunctuation
Imports System.Globalization
Module Example1
Public Sub Main()
' Define a string with a variety of character categories.
Dim s As String = "The car drove down the narrow, secluded road."
' Determine the category of each character.
For Each ch In s
Console.WriteLine("'{0}': {1}", ch, Char.GetUnicodeCategory(ch))
Next
End Sub
End Module
' The example displays the following output:
' 'T': UppercaseLetter
' 'h': LowercaseLetter
' 'e': LowercaseLetter
' ' ': SpaceSeparator
' 'r': LowercaseLetter
' 'e': LowercaseLetter
' 'd': LowercaseLetter
' ' ': SpaceSeparator
' 'c': LowercaseLetter
' 'a': LowercaseLetter
' 'r': LowercaseLetter
' ' ': SpaceSeparator
' 'd': LowercaseLetter
' 'r': LowercaseLetter
' 'o': LowercaseLetter
' 'v': LowercaseLetter
' 'e': LowercaseLetter
' ' ': SpaceSeparator
' 'd': LowercaseLetter
' 'o': LowercaseLetter
' 'w': LowercaseLetter
' 'n': LowercaseLetter
' ' ': SpaceSeparator
' 't': LowercaseLetter
' 'h': LowercaseLetter
' 'e': LowercaseLetter
' ' ': SpaceSeparator
' 'l': LowercaseLetter
' 'o': LowercaseLetter
' 'n': LowercaseLetter
' 'g': LowercaseLetter
' ',': OtherPunctuation
' ' ': SpaceSeparator
' 'n': LowercaseLetter
' 'a': LowercaseLetter
' 'r': LowercaseLetter
' 'r': LowercaseLetter
' 'o': LowercaseLetter
' 'w': LowercaseLetter
' ',': OtherPunctuation
' ' ': SpaceSeparator
' 's': LowercaseLetter
' 'e': LowercaseLetter
' 'c': LowercaseLetter
' 'l': LowercaseLetter
' 'u': LowercaseLetter
' 'd': LowercaseLetter
' 'e': LowercaseLetter
' 'd': LowercaseLetter
' ' ': SpaceSeparator
' 'r': LowercaseLetter
' 'o': LowercaseLetter
' 'a': LowercaseLetter
' 'd': LowercaseLetter
' '.': OtherPunctuation
En interne, pour les caractères en dehors de la plage ASCII (U+0000 à U+00FF), la GetUnicodeCategory méthode dépend des catégories Unicode signalées par la CharUnicodeInfo classe. À compter de .NET Framework 4.6.2, les caractères Unicode sont classés en fonction de la norme Unicode, version 8.0.0. Dans les versions de .NET Framework de .NET Framework 4 à .NET Framework 4.6.1, elles sont classées selon la norme Unicode, version 6.3.0.
Caractères et éléments de texte
Étant donné qu’un seul caractère peut être représenté par plusieurs Char objets, il n’est pas toujours significatif d’utiliser des objets individuels Char . Par exemple, l’exemple suivant convertit les points de code Unicode qui représentent les nombres égégéens zéro à 9 en unités de code codées UTF-16. Étant donné qu’il équivaut à des objets avec des Char caractères, il signale de manière inexacte que la chaîne résultante a 20 caractères.
using System;
public class Example5
{
public static void Main()
{
string result = String.Empty;
for (int ctr = 0x10107; ctr <= 0x10110; ctr++) // Range of Aegean numbers.
result += Char.ConvertFromUtf32(ctr);
Console.WriteLine("The string contains {0} characters.", result.Length);
}
}
// The example displays the following output:
// The string contains 20 characters.
open System
let result =
[ for i in 0x10107..0x10110 do // Range of Aegean numbers.
Char.ConvertFromUtf32 i ]
|> String.concat ""
printfn $"The string contains {result.Length} characters."
// The example displays the following output:
// The string contains 20 characters.
Module Example5
Public Sub Main()
Dim result As String = String.Empty
For ctr As Integer = &H10107 To &H10110 ' Range of Aegean numbers.
result += Char.ConvertFromUtf32(ctr)
Next
Console.WriteLine("The string contains {0} characters.", result.Length)
End Sub
End Module
' The example displays the following output:
' The string contains 20 characters.
Vous pouvez effectuer les opérations suivantes pour éviter l’hypothèse qu’un Char objet représente un caractère unique :
Vous pouvez utiliser un String objet dans son intégralité au lieu de travailler avec ses caractères individuels pour représenter et analyser du contenu linguistique.
Vous pouvez utiliser String.EnumerateRunes comme indiqué dans l’exemple suivant :
int CountLetters(string s) { int letterCount = 0; foreach (Rune rune in s.EnumerateRunes()) { if (Rune.IsLetter(rune)) { letterCount++; } } return letterCount; }
let countLetters (s: string) = let mutable letterCount = 0 for rune in s.EnumerateRunes() do if Rune.IsLetter rune then letterCount <- letterCount + 1 letterCount
Vous pouvez utiliser la StringInfo classe pour utiliser des éléments de texte au lieu d’objets individuels Char . L’exemple suivant utilise l’objet StringInfo pour compter le nombre d’éléments de texte dans une chaîne composée des nombres égégéens zéro à neuf. Étant donné qu’elle considère une paire de substitution un caractère unique, elle signale correctement que la chaîne contient dix caractères.
using System; using System.Globalization; public class Example4 { public static void Main() { string result = String.Empty; for (int ctr = 0x10107; ctr <= 0x10110; ctr++) // Range of Aegean numbers. result += Char.ConvertFromUtf32(ctr); StringInfo si = new StringInfo(result); Console.WriteLine("The string contains {0} characters.", si.LengthInTextElements); } } // The example displays the following output: // The string contains 10 characters.
open System open System.Globalization let result = [ for i in 0x10107..0x10110 do // Range of Aegean numbers. Char.ConvertFromUtf32 i ] |> String.concat "" let si = StringInfo result printfn $"The string contains {si.LengthInTextElements} characters." // The example displays the following output: // The string contains 10 characters.
Imports System.Globalization Module Example6 Public Sub Main() Dim result As String = String.Empty For ctr As Integer = &H10107 To &H10110 ' Range of Aegean numbers. result += Char.ConvertFromUtf32(ctr) Next Dim si As New StringInfo(result) Console.WriteLine("The string contains {0} characters.", si.LengthInTextElements) End Sub End Module ' The example displays the following output: ' The string contains 10 characters.
Si une chaîne contient un caractère de base qui a un ou plusieurs caractères combinés, vous pouvez appeler la String.Normalize méthode pour convertir la sous-chaîne en une seule unité de code encodée UTF-16. L’exemple suivant appelle la String.Normalize méthode pour convertir le caractère de base U+0061 (LETTRE MINUSCULE LATINE A) et combiner le caractère U+0308 (CO Mo INING DIAERESIS) en U+00E4 (LETTRE MINUSCULE LATINE A AVEC DIAERÈSE).
using System; public class Example2 { public static void Main() { string combining = "\u0061\u0308"; ShowString(combining); string normalized = combining.Normalize(); ShowString(normalized); } private static void ShowString(string s) { Console.Write("Length of string: {0} (", s.Length); for (int ctr = 0; ctr < s.Length; ctr++) { Console.Write("U+{0:X4}", Convert.ToUInt16(s[ctr])); if (ctr != s.Length - 1) Console.Write(" "); } Console.WriteLine(")\n"); } } // The example displays the following output: // Length of string: 2 (U+0061 U+0308) // // Length of string: 1 (U+00E4)
open System let showString (s: string) = printf $"Length of string: {s.Length} (" for i = 0 to s.Length - 1 do printf $"U+{Convert.ToUInt16 s[i]:X4}" if i <> s.Length - 1 then printf " " printfn ")\n" let combining = "\u0061\u0308" showString combining let normalized = combining.Normalize() showString normalized // The example displays the following output: // Length of string: 2 (U+0061 U+0308) // // Length of string: 1 (U+00E4)
Module Example3 Public Sub Main() Dim combining As String = ChrW(&H61) + ChrW(&H308) ShowString(combining) Dim normalized As String = combining.Normalize() ShowString(normalized) End Sub Private Sub ShowString(s As String) Console.Write("Length of string: {0} (", s.Length) For ctr As Integer = 0 To s.Length - 1 Console.Write("U+{0:X4}", Convert.ToUInt16(s(ctr))) If ctr <> s.Length - 1 Then Console.Write(" ") Next Console.WriteLine(")") Console.WriteLine() End Sub End Module ' The example displays the following output: ' Length of string: 2 (U+0061 U+0308) ' ' Length of string: 1 (U+00E4)
Opérations courantes
La Char structure fournit des méthodes pour comparer Char des objets, convertir la valeur de l’objet actuel Char en objet d’un autre type et déterminer la catégorie Unicode d’un Char objet :
Pour | Utiliser ces System.Char méthodes |
---|---|
Comparer des Char objets | CompareTo et Equals |
Convertir un point de code en chaîne | ConvertFromUtf32 Consultez également le Rune type. |
Convertir un Char objet ou une paire de substitution d’objets en point de Char code | Pour un caractère unique : Convert.ToInt32(Char) Pour une paire de substitution ou un caractère dans une chaîne : Char.ConvertToUtf32 Consultez également le Rune type. |
Obtenir la catégorie Unicode d’un caractère | GetUnicodeCategory Voir aussi Rune.GetUnicodeCategory. |
Déterminer si un caractère se trouve dans une catégorie Unicode particulière, comme le chiffre, la lettre, la ponctuation, le caractère de contrôle, etc. | IsControl, , IsDigit, IsSeparatorIsPunctuationIsSymbolIsNumberIsSurrogatePairIsLowSurrogateIsSurrogateIsUpperIsHighSurrogateIsLetterIsLetterOrDigitIsLowerIsWhiteSpace Consultez également les méthodes correspondantes sur le Rune type. |
Convertir un Char objet qui représente un nombre en type valeur numérique | GetNumericValue Voir aussi Rune.GetNumericValue. |
Convertir un caractère dans une chaîne en objet Char | Parse et TryParse |
Convertir un Char objet en objet String | ToString |
Modifier la casse d’un Char objet | ToLower, ToLowerInvariant, ToUpper et ToUpperInvariant Consultez également les méthodes correspondantes sur le Rune type. |
Valeurs de caractères et interopérabilité
Lorsqu’un type managé, représenté sous la forme d’une unité de code codé en unicode UTF-16, est passé au code non managé Char , le marshaller d’interopérabilité convertit le jeu de caractères défini en ANSI par défaut. Vous pouvez appliquer l’attribut DllImportAttribute aux déclarations d’appel de plateforme et StructLayoutAttribute à l’attribut à une déclaration COM Interop pour contrôler le jeu de caractères utilisé par un type marshalé Char .