我在 C#.NET 中编写了一些漂亮的字符串操作密集型代码,并对我记得不久前读过的一些 Joel Spolsky 文章感到好奇:
http://www.joelonsoftware.com/articles/fog0000000319.html
http://www.joelonsoftware.com/articles/Unicode.html
那么,.NET 是如何做到的呢?每个字符两个字节?有一些 Unicode 字符^H^H^H^H^H 代码点需要更多。长度是如何编码的?
我在 C#.NET 中编写了一些漂亮的字符串操作密集型代码,并对我记得不久前读过的一些 Joel Spolsky 文章感到好奇:
http://www.joelonsoftware.com/articles/fog0000000319.html
http://www.joelonsoftware.com/articles/Unicode.html
那么,.NET 是如何做到的呢?每个字符两个字节?有一些 Unicode 字符^H^H^H^H^H 代码点需要更多。长度是如何编码的?
在 Jon Skeet 出现之前,有一个链接指向他关于C#字符串的优秀博客。
至少在当前实现中,字符串占用 20+(n/2)*4 个字节(将 n/2 的值向下舍入),其中 n 是字符串中的字符数。字符串类型的不寻常之处在于对象本身的大小不同
.NET 使用UTF-16。
“字符串中的每个 Unicode 字符由一个 Unicode 标量值定义,也称为 Unicode 码点或 Unicode 字符的序数(数字)值。每个码点使用 UTF-16 编码进行编码,每个码点的数值编码元素由 Char 对象表示。”
String 对象非常复杂,无法提供一个简短的示例并将给定的文本编码为字符串,将生成的内存内容显示为字节值序列。
String 对象将文本表示为一系列 UTF-16 代码单元。它是 System.Char 对象的顺序集合,每个对象对应一个 UTF-16 代码单元。单个 Char 对象通常表示单个代码点。一个代码点可能需要多个编码元素,即。多个 Char 对象(补充代码点(或代理对)和字素)。注意:UTF-16 是一种可变宽度编码。
字符串的长度作为 String 对象的属性存储在内存中。注意:String 对象可以包含嵌入的空字符,这些字符计为字符串长度的一部分(与 C 和 C++ 不同,空字符表示字符串的结尾,因此不必额外存储长度)。存储 Char 对象的内部字符数组实际上可以比字符串的长度长(分配策略的结果)。
如果您难以创建正确的编码来使用(因为您找不到任何名为 System.Text.Encoding.UTF16 的属性),则 UTF-16 实际上是 System.Text.Encoding.Unicode,如本示例中所使用的:
string unicodeString = "pi stands for \u03a0";
byte[] encoded = System.Text.Encoding.Unicode.GetBytes(unicodeString);
构造函数 Encoding.Unicode,没有任何参数,实际上是使用 little endian 字节顺序创建一个 UnicodeEncoding 对象。UnicodeEncoding 类(实现 UTF-16 编码)也能够处理大端(也支持字节顺序标记的处理)。英特尔平台的本机字节顺序是小端,因此 .NET(和 Windows)以这种格式存储 Unicode 字符串可能更有效。