.NET String的内部格式是什么?

时间:2009-06-19 16:40:08

标签: .net string unicode internals

我在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代码点需要更多。长度是如何编码的?

3 个答案:

答案 0 :(得分:17)

在Jon Skeet出现之前,这是指向他在C#中excellent blog on strings的链接。

  

至少在当前的实现中,字符串占用20+(n / 2)* 4字节(向下舍入n / 2的值),其中n是字符串中的字符数。字符串类型不寻常,因为对象本身的大小不同

答案 1 :(得分:9)

.NET使用UTF-16

来自System.String on MSDN

“字符串中的每个Unicode字符都由Unicode标量值定义,也称为Unicode代码点或Unicode字符的序数(数字)值。每个代码点使用UTF-16编码进行编码,并且数字编码的每个元素的值由Char对象表示。“

答案 2 :(得分:1)

String对象非常复杂,无法提供一个简短的示例并将给定的文本编码为字符串,从而将生成的内存内容显示为字节值序列。

一个String对象将文本表示为一系列UTF-16代码单元。它是System.Char对象的顺序集合,每个对象对应于一个UTF-16代码单元。 一个Char对象通常代表一个代码点。一个代码点可能需要多个编码元素,即。多个Char对象(辅助代码点(或替代对)和字素)。注意:UTF-16是可变宽度编码。

字符串的长度作为String对象的属性存储在内存中。注意:String对象可以包含嵌入的null字符,这些字符算作字符串长度的一部分(与C和C ++相反,其中的null字符表示字符串的结尾,因此不必另外存储长度)。内部字符数组(存储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实际上使用小尾数字节顺序创建UnicodeEncoding对象。 UnicodeEncoding类(实现UTF-16编码)也能够处理大字节序(也支持字节顺序标记的处理)。 Intel平台的本机字节顺序为低位字节序,因此.NET(和Windows)以这种格式存储Unicode字符串可能更有效。