27

更新的问题¹

关于字符类、比较、排序、规范化和排序规则,哪些 .NET 平台支持哪些 Unicode 版本?

原始问题

我记得有些模糊地读过 .NET 支持 Unicode 3.0 版,并且内部 UTF-16 编码并不是真正的 UTF-16,但实际上使用的是 UCS-2,这是不一样的。例如,似乎 U+FFFF 以上的字符是不可能的,即考虑:

string s = "\u1D7D9"; // ("Mathematical double-struck digit one") 

它存储字符串"ᵽ9"

我基本上是在寻找以下答案的明确参考:

  • 如果在 .NET 中不是真正的 UTF-16,它是什么?
  • .NET 支持哪个版本的 Unicode?
  • 如果在不久的将来不支持或计划不支持最新版本,是否有人知道(非)商业库或我如何解决此问题?

¹)我随着时间的推移更新了这个问题,对于答案和更大的社区来说似乎更合适。我留下了原始问题,以代替评论中已回答的部分。旧的 UCS-2(无代理)也用于现在古老的 32 位 Windows 版本,.NET 在内部一直使用 UTF-16(有代理)。

4

4 回答 4

19

在内部,.NET 是 UTF-16。在某些情况下,例如当 ASP.NET 写入响应时,默认情况下它使用 UTF-8。他们都可以处理更高的飞机。

人们有时将 .NET 称为 UCS2 的原因是(我认为,因为我看不到其他原因) Char 是严格 16 位的,并且单个 Char 不能用于表示上层平面。但是,Char 确实具有静态方法重载(例如Char.IsLetter),可以对字符串中的高平面 UTF-16 字符进行操作。字符串存储为真正的 UTF-16。

您可以使用大写直接处理高 Unicode 代码点\U- 例如"\U0001D7D9"- 但同样,只能在字符串内部,而不是字符。

至于 Unicode 版本,来自 MSDN 文档

“在 .NET Framework 4 中,排序、大小写、规范化和 Unicode 字符信息与 Windows 7 同步,符合Unicode 5.1 标准。”

更新 1:然而,值得注意的是,这并不意味着支持整个Unicode 5.1 - 无论是在 Windows 7 中还是在 .NET 4.0 中

Windows 8 以 Unicode 6.0 为目标——我猜测 .NET Framework 4.5 可能会与之同步,但没有发现任何来源确认它。再一次,这并不意味着整个标准都已实施。

更新 2: 关于 Roslyn 的此注释确认底层平台定义了对编译器的 Unicode 支持,并在代码链接中解释了 C# 6.0 支持 Unicode 6.0 及更高版本(因此对 C# 标识符进行了重大更改)。

更新 3:从 .NET 版本 4.5 开始,引入了一个新类SortVersion,通过调用静态属性来获取支持的 Unicode 版本SortVersion.FullVersion。在同一页上,微软解释说 .NET 4.0 在所有平台上支持 Unicode 5.0,.NET 4.5 在 Windows 7 上支持 Unicode 5.0,在 Windows 8 上支持 Unicode 6.0。这与官方的“什么是新的”声明略有不同,这里谈到版本 5.x 和 6.0 分别。根据我自己(编辑:Abel)的经验,在大多数情况下,似乎在 .NET 4.0 中,至少字符类支持 Unicode 5.1,但我没有测试排序、规范化和排序规则。这似乎与上面引用的MSDN中所说的一致。

于 2012-02-06T15:49:51.010 回答
5

支持该字符。需要注意的一点是,对于超过 2 个字节的 unicode 字符,您必须使用大写的 '\U' 声明它们,如下所示:

string text = "\U0001D7D9"

如果您在文本块中使用该字符创建 WPF 应用程序,它应该完美地呈现双一字符。

于 2012-02-06T15:42:12.593 回答
4

MSDN 在这里简要介绍了它:http: //msdn.microsoft.com/en-us/library/9b1s4yhz (v=vs.90).aspx

我试过这个:

    static void Main(string[] args) {
        string someText = char.ConvertFromUtf32(0x1D7D9);
        using (var stream = new MemoryStream()) {
            using (var writer = new StreamWriter(stream, Encoding.UTF32)) {
                writer.Write(someText);
                writer.Flush();
            }
            var bytes = stream.ToArray();
            foreach (var oneByte in bytes) {
                Console.WriteLine(oneByte.ToString("x"));
            }
        }
    }

并得到一个字节数组的转储,其中包含正确的 BOM 和\u1D7D9代码点的正确表示,用于这些编码:

  • UTF8
  • UTF32
  • 统一码(UTF-16)

所以我的猜测是支持更高的平面,并且 UTF-16 真的是 UTF-16 (而不是 UCS-2)

于 2012-02-06T15:36:17.340 回答
0

.NET Framework 4.6 and 4.5 and 4 and 3.5 and 3.0 - The Unicode Standard, version 5.0 .NET Framework 2.0 and 1.1 - The Unicode Standard, Version 3.1

The complete answers can be found here under the section Remarks.

于 2015-05-12T15:15:30.903 回答