C#和UTF-16字符

时间:2009-03-30 12:51:10

标签: c# unicode

C#中是否可以使用不在平面0中的UTF-32字符作为字符?

string s = ""; // valid
char c = ''; // generates a compiler error ("Too many characters in character literal")

在s中它由两个字符表示,而不是一个。

编辑:我的意思是,是否有一个字符AN字符串类型,每个字符支持完整的unicode,UTF-32或UTF-8?例如,如果我想在字符串中的utf-32(可能不在plane0中)字符上进行for循环。

3 个答案:

答案 0 :(得分:9)

string类表示UTF-16编码的文本块,string中的每个char表示UTF-16代码值。

虽然没有代表单个Unicode代码点的BCL类型,但是以方法重载的形式支持超出平面0的Unicode字符,它采用string和索引而不是{{1} }。例如,GetUnicodeCategory(char)类上的静态System.Globalization.CharUnicodeInfo方法具有相应的GetUnicodeCategory(string,int)方法,该方法将识别从指定索引开始的简单字符或代理项对。


要遍历char中的文本元素,您可以使用System.Globalization.StringInfo类上的方法。这里,“文本元素”对应于屏幕上显示的单个字符。这意味着组合字符(string =“ā̈”)和代理对("a" =“ ”)的简单字符("a\u0304\u0308")将被视为单个文本元件。

具体来说,GetTextElementEnumerator静态方法将允许您枚举"\uD950\uDF21"中的每个文本元素(请参阅链接的MSDN页面以获取代码示例)。

答案 1 :(得分:4)

我只是从Java知道这个问题并在回答之前检查documentation on char,实际上.NET / C#和Java中的行为几乎相同。

似乎确实char被定义为16位,并且绝对不能保存在平面0之外的任何内容。只有String / string能够处理这些字符。在char - 数组中,它将表示为two surrogate characters

答案 2 :(得分:3)

C#System.String支持UTF-32就好了,但你不能遍历字符串,就像它是System.Char的数组或使用IEnumerable一样。

例如:

// iterating through a string NO UTF-32 SUPPORT
for (int i = 0; i < sample.Length; ++i)
{
    if (Char.IsDigit(sample[i]))
    {
        Console.WriteLine("IsDigit");
    }
    else if (Char.IsLetter(sample[i]))
    {
        Console.WriteLine("IsLetter");
    }
}

// iterating through a string WITH UTF-32 SUPPORT
for (int i = 0; i < sample.Length; ++i)
{
    if (Char.IsDigit(sample, i))
    {
        Console.WriteLine("IsDigit");
    }
    else if (Char.IsLetter(sample, i))
    {
        Console.WriteLine("IsLetter");
    }

    if (Char.IsSurrogate(sample, i))
    {
        ++i;
    }
}

请注意Char.IsDigit和Char.IsLetter调用中的细微差别。而String.Length总是16位“字符”的数量,而不是UTF-32意义上的“字符”数。

偏离主题,但应用程序处理国际语言完全不需要UTF-32支持,除非您有一个特定的商业案例用于模糊的历史/技术语言。