System.Char 構造体

この記事では、この API のリファレンス ドキュメントへの補足的な解説を提供します。

構造体は Char 、UTF-16 エンコードを使用して Unicode コード ポイントを表します。 オブジェクトの Char 値は、その 16 ビット数値 (序数) 値です。

Unicode、スカラー値、コード ポイント、サロゲート ペア、UTF-16、およびRune型に慣れていない場合は、「.NET での文字エンコードの概要」を参照してください

この記事では、オブジェクトと文字の関係を Char 調べ、インスタンスで Char 実行される一般的なタスクについて説明します。 これらのタスクの一部を Rune 実行する代わりに Char 、.NET Core 3.0 で導入された型を検討することをお勧めします。

Char オブジェクト、Unicode 文字、および文字列

Stringオブジェクトは、テキストのChar文字列を表す構造体のシーケンシャル コレクションです。 ほとんどの Unicode 文字は 1 つの Char オブジェクトで表すことができますが、基本文字、サロゲート ペア、結合文字シーケンスとしてエンコードされる文字は、複数 Char のオブジェクトによって表されます。 このため、オブジェクト内のCharString構造体は、必ずしも 1 つの Unicode 文字と等しいとは限りません。

次の場合、1 つの Unicode 文字を表すために複数の 16 ビット コード単位が使用されます。

  • グリフ。1 文字または基本文字の後に 1 つ以上の結合文字が続く場合があります。 たとえば、文字 ä は、コード単位が U+0061 のオブジェクトの後Charに、コード単位が U+0308 であるオブジェクトによって表Charされます。 (文字 ä は、U+00E4 のコード単位を持つ 1 つの Char オブジェクトで定義することもできます)。次の例は、文字 ä が 2 つの Char オブジェクトで構成されていることを示しています。

    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:
    '       ä
    
  • Unicode 基本多言語プレーン (BMP) の外側の文字。 Unicode では、平面 0 を表す BMP に加えて 16 個の平面がサポートされています。 Unicode コード ポイントは、プレーンを含む 21 ビット値によって UTF-32 で表されます。 たとえば、U+1D160 は MUSICAL SY MB (メガバイト)OL 8 番目の NOTE 文字を表します。 UTF-16 エンコードには 16 ビットしかないため、BMP の外部の文字は UTF-16 のサロゲート ペアによって表されます。 次の例は、U+1D160 に相当する UTF-32 (MUSICAL SY MB (メガバイト)OL 8 分注文字) が U+D834 U+DD60 であることを示しています。 U+D834 は上位サロゲートです。上位サロゲートの範囲は U+D800 から U+DBFF です。 U+DD60 は低サロゲートです。低サロゲートの範囲は 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
    

文字と文字カテゴリ

各 Unicode 文字または有効なサロゲート ペアは、Unicode カテゴリに属しています。 .NET では、Unicode カテゴリは列挙体のUnicodeCategoryメンバーによって表され、たとえば 、UnicodeCategory.LowercaseLetter、などのUnicodeCategory.SpaceSeparatorUnicodeCategory.CurrencySymbolが含まれます。

文字の Unicode カテゴリを特定するには、メソッドを GetUnicodeCategory 呼び出します。 たとえば、次の例では、文字列内の GetUnicodeCategory 各文字の Unicode カテゴリを表示する呼び出しを行います。 この例は、インスタンスにサロゲート ペア 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

内部的には、ASCII 範囲外の文字 (U+0000 ~ U+00FF) の場合、 GetUnicodeCategory メソッドはクラスによって報告される CharUnicodeInfo Unicode カテゴリに依存します。 .NET Framework 4.6.2 以降では、Unicode 文字は Unicode 標準バージョン 8.0.0 に基づいて分類されます。 .NET Framework 4 から .NET Framework 4.6.1 への .NET Framework のバージョンでは、Unicode Standard バージョン 6.3.0基づいて分類されます。

文字とテキスト要素

1 つの文字を複数 Char のオブジェクトで表すことができるため、個々 Char のオブジェクトを操作することは必ずしも意味がありません。 たとえば、次の例では、0 から 9 までのエーゲ数字を表す Unicode コード ポイントを UTF-16 でエンコードされたコード単位に変換します。 オブジェクトが誤って文字と等 Char しいため、結果の文字列に 20 文字が含まれていると不正確に報告されます。

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.

オブジェクトが 1 つの文字を表すという Char 前提を回避するには、次の操作を行います。

  • 個々の文字を String 操作して言語コンテンツを表したり分析したりするのではなく、オブジェクト全体を操作できます。

  • 次の例に示すように使用 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
    
  • このクラスを使用して、個々CharStringInfoオブジェクトではなくテキスト要素を操作できます。 次の例では、オブジェクトを StringInfo 使用して、0 から 9 までのエーゲ数字で構成される文字列内のテキスト要素の数をカウントします。 サロゲート ペアは 1 文字と見なされるため、文字列に 10 文字が含まれていることが正しく報告されます。

    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.
    
  • 文字列に 1 つ以上の組み合わせ文字を含む基本文字が含まれている場合は、メソッドを String.Normalize 呼び出して、部分文字列を 1 つの UTF-16 でエンコードされたコード単位に変換できます。 次の例では、メソッドをString.Normalize呼び出して、基本文字 U+0061 (LATIN SMALL LETTER A) を変換し、文字 U+0308 (CO MB (メガバイト)INING DIAERESIS) を U+00E4 (LATIN SMALL LETTER A WITH 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)
    

一般的な操作

この構造体は Char 、オブジェクトを比較 Char し、現在 Char のオブジェクトの値を別の型のオブジェクトに変換し、オブジェクトの Unicode カテゴリを決定するメソッドを Char 提供します。

目的 これらの System.Char メソッドを使用する
オブジェクトの比較Char CompareTo および Equals
コード ポイントを文字列に変換する ConvertFromUtf32

型も Rune 参照してください。
Charオブジェクトまたはオブジェクトのサロゲート ペアCharをコード ポイントに変換する 1 文字の場合: Convert.ToInt32(Char)

サロゲート ペアまたは文字列内の文字の場合: Char.ConvertToUtf32

型も Rune 参照してください。
文字の Unicode カテゴリを取得する GetUnicodeCategory

参照 Rune.GetUnicodeCategory.
数字、文字、句読点、制御文字など、特定の Unicode カテゴリに文字があるかどうかを判断する IsControl, IsDigit, IsHighSurrogate, IsLetter, IsLetterOrDigit, , IsLower, IsLowSurrogate, IsNumber, IsPunctuation, , IsSeparator, IsSurrogate, IsSurrogatePair, , IsSymbol, IsUpperand IsWhiteSpace

型の Rune 対応するメソッドも参照してください。
数値を Char 表すオブジェクトを数値型に変換する GetNumericValue

参照 Rune.GetNumericValue.
文字列内の文字をオブジェクトに変換するChar Parse および TryParse
オブジェクトをCharオブジェクトに変換するString ToString
オブジェクトの大文字と小文字を変更するChar ToLowerToLowerInvariantToUpper、および ToUpperInvariant

型の Rune 対応するメソッドも参照してください。

Char 値と相互運用機能

Unicode UTF-16 でエンコードされたコード単位として表されるマネージド Char 型がアンマネージ コードに渡されると、相互運用マーシャラーは既定で文字セットを ANSI に変換します。 属性を DllImportAttribute プラットフォーム呼び出し宣言に適用し、属性を StructLayoutAttribute COM 相互運用機能宣言に適用して、マーシャリングされた Char 型で使用される文字セットを制御できます。