System.Char-Struktur

Dieser Artikel enthält ergänzende Hinweise zur Referenzdokumentation für diese API.

Die Char Struktur stellt Unicode-Codepunkte mithilfe der UTF-16-Codierung dar. Der Wert eines Char Objekts ist sein 16-Bit-numerischer Wert (Ordnungszahl).

Wenn Sie mit Unicode, Skalarwerten, Codepunkten, Ersatzpaaren, UTF-16 und dem Rune Typ nicht vertraut sind, lesen Sie die Einführung in die Zeichencodierung in .NET.

In diesem Artikel wird die Beziehung zwischen einem Char Objekt und einem Zeichen untersucht und einige allgemeine Aufgaben behandelt, die mit Char Instanzen ausgeführt werden. Es wird empfohlen, den Typ zu berücksichtigen, der Rune in .NET Core 3.0 eingeführt wurde, als Alternative zum Char Ausführen einiger dieser Aufgaben.

Zeichenobjekte, Unicode-Zeichen und Zeichenfolgen

Ein String Objekt ist eine sequenzielle Auflistung von Char Strukturen, die eine Textzeichenfolge darstellen. Die meisten Unicode-Zeichen können durch ein einzelnes Char Objekt dargestellt werden, aber ein Zeichen, das als Basiszeichen, Ersatzpaar und/oder kombinierte Zeichenfolge codiert ist, wird durch mehrere Char Objekte dargestellt. Aus diesem Grund entspricht eine Char Struktur in einem String Objekt nicht unbedingt einem einzelnen Unicode-Zeichen.

In den folgenden Fällen werden mehrere 16-Bit-Codeeinheiten verwendet, um einzelne Unicode-Zeichen darzustellen:

  • Glyphen, die aus einem einzelnen Zeichen oder einem Basiszeichen bestehen können, gefolgt von einem oder mehreren kombinierten Zeichen. Beispielsweise wird das Zeichen "ä" durch ein Char Objekt dargestellt, dessen Codeeinheit U+0061 ist, gefolgt von einem Char Objekt, dessen Codeeinheit U+0308 ist. (Das Zeichen ä kann auch durch ein einzelnes Char Objekt definiert werden, das über eine Codeeinheit von U+00E4 verfügt.) Das folgende Beispiel veranschaulicht, dass das Zeichen ä aus zwei Char Objekten besteht.

    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:
    '       ä
    
  • Zeichen außerhalb der Unicode Basic Multilingual Plane (BMP). Unicode unterstützt zusätzlich zum BMP sechszehn Ebenen, die Ebene 0 darstellt. Ein Unicode-Codepunkt wird in UTF-32 durch einen 21-Bit-Wert dargestellt, der die Ebene enthält. U+1D160 stellt z. B. das ZEICHEN MUSICAL SYMBOL ACHTE NOTE dar. Da die UTF-16-Codierung nur 16 Bit aufweist, werden Zeichen außerhalb des BMP durch Ersatzpaare in UTF-16 dargestellt. Das folgende Beispiel veranschaulicht, dass das UTF-32-Äquivalent von U+1D160, das MUSICAL SYMBOL ACHTE NOTE-Zeichen, U+D834 U+DD60 ist. U+D834 ist der hohe Ersatz; Hohe Surrogate reichen von U+D800 bis U+DBFF. U+DD60 ist der niedrige Ersatz; Niedrige Surrogate reichen von U+DC00 bis 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
    

Zeichen und Zeichenkategorien

Jedes Unicode-Zeichen oder gültige Ersatzpaar gehört zu einer Unicode-Kategorie. In .NET werden Unicode-Kategorien durch Member der UnicodeCategory Enumeration dargestellt und enthalten Werte wie UnicodeCategory.CurrencySymbol, , UnicodeCategory.LowercaseLetterund UnicodeCategory.SpaceSeparator, z. B. .

Rufen Sie die GetUnicodeCategory Methode auf, um die Unicode-Kategorie eines Zeichens zu ermitteln. Im folgenden Beispiel wird beispielsweise die GetUnicodeCategory Unicode-Kategorie jedes Zeichens in einer Zeichenfolge angezeigt. Das Beispiel funktioniert nur dann ordnungsgemäß, wenn in der String Instanz keine Ersatzpaare vorhanden sind.

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

Intern hängt die GetUnicodeCategory Methode für Zeichen außerhalb des ASCII-Bereichs (U+0000 bis U+00FF) von unicode-Kategorien ab, die von der CharUnicodeInfo Klasse gemeldet werden. Ab .NET Framework 4.6.2 werden Unicode-Zeichen basierend auf dem Unicode Standard, Version 8.0.0, klassifiziert. In Versionen von .NET Framework von .NET Framework 4 bis .NET Framework 4.6.1 werden sie basierend auf Dem Unicode Standard, Version 6.3.0, klassifiziert.

Zeichen und Textelemente

Da ein einzelnes Zeichen durch mehrere Char Objekte dargestellt werden kann, ist es nicht immer sinnvoll, mit einzelnen Char Objekten zu arbeiten. Im folgenden Beispiel werden beispielsweise die Unicode-Codepunkte konvertiert, die die Ägäis-Zahlen 0 bis 9 in UTF-16-codierte Codeeinheiten darstellen. Da objekte fälschlicherweise mit Zeichen gleichgesetzt Char werden, meldet sie ungenau, dass die resultierende Zeichenfolge 20 Zeichen enthält.

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.

Gehen Sie wie folgt vor, um die Annahme zu vermeiden, dass ein Char Objekt ein einzelnes Zeichen darstellt:

  • Sie können vollständig mit einem String Objekt arbeiten, anstatt mit den einzelnen Zeichen zu arbeiten, um sprachliche Inhalte darzustellen und zu analysieren.

  • Sie können wie im folgenden Beispiel gezeigt verwenden String.EnumerateRunes :

    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
    
  • Sie können die StringInfo Klasse verwenden, um mit Textelementen anstelle einzelner Char Objekte zu arbeiten. Im folgenden Beispiel wird das StringInfo Objekt verwendet, um die Anzahl der Textelemente in einer Zeichenfolge zu zählen, die aus den Ägäischen Zahlen 0 bis neun besteht. Da es ein Ersatzpaar als einzelnes Zeichen betrachtet, meldet es ordnungsgemäß, dass die Zeichenfolge zehn Zeichen enthält.

    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.
    
  • Wenn eine Zeichenfolge ein Basiszeichen mit mindestens einem Kombinationszeichen enthält, können Sie die String.Normalize Methode aufrufen, um die Teilzeichenfolge in eine einzelne UTF-16-codierte Codeeinheit zu konvertieren. Im folgenden Beispiel wird die String.Normalize Methode aufgerufen, um das Basiszeichen U+0061 (LATIN SMALL LETTER A) zu konvertieren und das Kombinieren von Zeichen U+0308 (KOMBINATION VON DIAERESIS) in U+00E4 (LATEINISCHER KLEINER BUCHSTABE A MIT DIAERESIS).

    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)
    

Allgemeine Vorgänge

Die Char Struktur stellt Methoden zum Vergleichen Char von Objekten bereit, konvertiert den Wert des aktuellen Char Objekts in ein Objekt eines anderen Typs und bestimmt die Unicode-Kategorie eines Char Objekts:

Vorgehensweise Verwenden Sie diese System.Char Methoden.
Vergleichen von Char Objekten CompareTo und Equals
Konvertieren eines Codepunkts in eine Zeichenfolge ConvertFromUtf32

Siehe auch den Rune Typ.
Konvertieren eines Char Objekts oder eines Ersatzpaars von Char Objekten in einen Codepunkt Für ein einzelnes Zeichen: Convert.ToInt32(Char)

Für ein Ersatzpaar oder ein Zeichen in einer Zeichenfolge: Char.ConvertToUtf32

Siehe auch den Rune Typ.
Abrufen der Unicode-Kategorie eines Zeichens GetUnicodeCategory

Siehe auch Rune.GetUnicodeCategory.
Bestimmen, ob sich ein Zeichen in einer bestimmten Unicode-Kategorie befindet, z. B. Ziffer, Buchstabe, Interpunktion, Steuerelementzeichen usw. IsControl, IsDigit, , IsHighSurrogate, IsLetter, IsLowerIsLetterOrDigitIsLowSurrogate, IsNumber, IsPunctuation, und IsSeparatorIsSurrogateIsSurrogatePairIsSymbolIsUpperIsWhiteSpace

Siehe auch entsprechende Methoden für den Rune Typ.
Konvertieren eines Char Objekts, das eine Zahl darstellt, in einen numerischen Werttyp GetNumericValue

Siehe auch Rune.GetNumericValue.
Konvertieren eines Zeichens in einer Zeichenfolge in ein Char Objekt Parse und TryParse
Konvertieren eines Char Objekts in ein String Objekt ToString
Ändern der Groß-/Kleinschreibung eines Char Objekts ToLower, ToLowerInvariant, ToUpper und ToUpperInvariant

Siehe auch entsprechende Methoden für den Rune Typ.

Zeichenwerte und Interoperabilität

Wenn ein verwalteter Char Typ, der als Unicode UTF-16-codierte Codeeinheit dargestellt wird, an nicht verwalteten Code übergeben wird, konvertiert der Interop-Marshaller standardmäßig den Zeichensatz in ANSI. Sie können das DllImportAttribute Attribut auf Plattform aufrufende Deklarationen und das StructLayoutAttribute Attribut auf eine COM-Interopdeklaration anwenden, um zu steuern, welches Zeichensatz ein gemarsteter Char Typ verwendet.