【问题标题】:Can Visual Studio handles U+20000 Unicode as char? How?Visual Studio 可以将 U+20000 Unicode 处理为 char 吗?如何?
【发布时间】:2014-06-12 19:03:20
【问题描述】:

有些 Unicode 代码超过一个字节,Visual Studio 可以处理这些字符吗?怎么样?

http://www.unicode.org 以下为 CJK 版本。现在一个字符可能超过一个字节。

  • 中日韩统一表意文字扩展 B(U+20000 到 U+2A6D6)
  • 中日韩统一表意文字扩展 C(U+2A700 到 U+2B734)
  • 中日韩统一表意文字扩展 D(U+2B740 到 U+2B81D)
  • CJK 兼容表意文字补充(U+2F800 到 U+2FA1D)

以下语句在 Visual Studio 2012 上对我来说失败:

char ch = '\u2A6D6';

我还没有尝试过 Visual Studio 2013 / Visual Studio 2015。

【问题讨论】:

  • 它们被处理为两个字符,一个低代理和一个高代理,形成一个surrogate pair
  • JavaScript has a Unicode problem。 C# 的解释完全相同。
  • Visual Studio 是如何失败的?
  • @LasseV.Karlsen 这里的“失败”是指 Visual Studio 无法识别 C# 语句 - 语法错误。
  • 所以你的意思是 C# 编译器。

标签: c# visual-studio-2010 visual-studio visual-studio-2012 unicode


【解决方案1】:

此代码点不适合 char,因为 char 只有 16 位,因此仅支持最多 65535 个代码点。基本多语言平面 (BMP) 之外的字符可以编码为两个 UTF-16 代码-使用代理对的字符串中的单位。

char.ConvertFromUtf32(0x2A6D6) 返回一个包含两个chars、"\uD869\uDED6"的字符串


代码点 U+10000 到 U+10FFFF

来自其他平面(称为补充平面)的代码点通过称为代理对的 16 位代码单元对以 UTF-16 编码,采用以下方案:

  • 从代码点中减去 0x010000,在 0..0x0FFFFF 范围内留下一个 20 位数。
  • 前十位(0..0x03FF 范围内的数字)被添加到 0xD800 以提供第一个代码单元或前导代理,它将在 0xD800..0xDBFF 范围内。 (以前版本的 Unicode 标准将这些称为高级代理。)
  • 将低十位(也在 0..0x03FF 范围内)添加到 0xDC00 以提供第二个代码单元或跟踪代理,它将在 0xDC00..0xDFFF 范围内。 (以前版本的 Unicode 标准将这些称为低代理。)

来自wikipedia - UTF-16

【讨论】:

  • 那么C#中的char作为Unicode字符的含义是什么?
  • @Nobody A .NET char 表示 UTF-16 代码单元,而不是 unicode 代码点。
  • 我可以得出结论:1.) C# 中的字符不是 UNICODE 中的字符! 2.) C# 中的字符串可以是 UNICODE 中的单个字符。 3.) string.Length 在这种情况下计算 Unicode 字符时可能是错误的。 4.) Char.IsSurrogate() 和 Char.IsHighSurrogate() 在这种情况下非常有用。
【解决方案2】:

Visual Studio 应该能够很好地处理它们。但是,您的代码在 C# 中是不合法的。正如@CodesInChaos 所提到的,.NET 中的chars 是 UTF-16 代码单元,而不是 Unicode 代码点。 \uxxxx 转义序列只允许 4 个十六进制数字(2 个字节)。在 C# 中,您通常会对 0xFFFF 以上的代码点使用 \Uxxxxxxxx 转义,但请注意,此转义序列被转换为两个代理 UTF-16 代码单元(即两个 .NET chars),因此它们不能分配给char 数据类型。如果您需要使用char,则必须按照@CodesInChaos 的建议使用代理,否则您通常会执行以下操作:

string s = "\U0002A6D6";

旁注:我不会将扩展称为最近 2 个字节,它发生在 almost 20 years ago

【讨论】:

  • 谢谢,我从问题中取出了“最近”。
猜你喜欢
  • 2021-07-31
  • 2013-09-16
  • 2011-06-27
  • 2010-10-05
  • 1970-01-01
  • 1970-01-01
  • 2018-05-09
  • 2019-07-14
  • 1970-01-01
相关资源
最近更新 更多