文档和语言因VS 2008和2010而异:
在内部,文本存储为 Char对象的只读集合,每个Char对象代表一个以UTF-16 编码的Unicode字符。 ... 字符串的长度表示字符数,无论字符是否由Unicode代理项对组成。要访问字符串中的各个Unicode代码点,请使用StringInfo对象。 - http://msdn.microsoft.com/en-us/library/ms228362%28v=vs.90%29.aspx
在内部,文本存储为 Char对象的顺序只读集合。 ... 字符串的Length属性表示它包含的Char对象的数量,而不是Unicode字符的数量。要访问字符串中的各个Unicode代码点,请使用StringInfo对象。 - http://msdn.microsoft.com/en-us/library/ms228362%28v=VS.100%29.aspx
两种情况下使用的语言都没有明确区分“字符”,“Unicode字符”,“字符类”,“Unicode代理项对”和“Unicode代码点”。
VS2008文档中的语言表明“字符串表示字符的数量,无论字符是否由Unicode代理项对组成”似乎是将“character”定义为可能是Unicode代理对的结果的对象,这表明它可能代表4字节序列而不是2字节序列。它还特别指出一个“char”对象以UTF-16编码,这表明它可以代表一个代理对(4个字节而不是2个字节)。我很确定这是错的。
VS2010文档更加精确。它区分了“char”和“Unicode character”,但不区分“Unicode character”和“Unicode code point”。如果代码点引用代理对的一半,并且“Unicode字符”代表完整对,则“Char”类的名称不正确,并且根本不引用“Unicode字符”(他们声明它不是),它实际上是一个Unicode代码点。
以下两个陈述都是真的吗? (是的,我想。)
答案 0 :(得分:27)
String.Length不考虑代理对;但是, StringInfo.LengthInTextElements
方法可以。
StringInfo.SubstringByTextElements
类似于String.Substring,但它对“文本元素”进行操作,例如代理对和组合字符以及普通字符。这两种方法的功能都基于StringInfo.ParseCombiningCharacters方法,该方法提取每个文本元素的起始索引并将它们存储在私有数组中。
“.NET Framework将文本元素定义为文本单元 显示为单个字符,即字形。文本元素 可以是基本字符,代理项对或组合字符 顺序。“ - http://msdn.microsoft.com/en-us/library/system.globalization.stringinfo.aspx
答案 1 :(得分:20)
String.Length不考虑代理对,它只计算UTF-16字符(即字符总是 2字节) - 代理对被计为2个字符。
答案 2 :(得分:1)
我认为都是假的。如果您询问unicode代码点的数量但是您询问了“长度”,那么第二个问题就是如此。 String的Length是其元素的计数。如果字符串中只有来自BMP(基本多语言平面)的unicode代码点,则长度等于unicode字符/代码点的数量。如果存在来自BMP之外的代码点或孤立的代理项(高或低代理项不显示为有序对),则长度不等于字符/代码点的数量。
首先,String是一堆单词,单词列表,单词数组或单词流。它的内容是16位字,就是这样。命名元素“char”或“wchar”是关于unicode字符的罪。因为unicode字符的代码点大于0xFFFF,所以它不能存储在16位宽的类型中,如果这种类型被称为char或wchar,那就更糟了,因为它只能保存限制为0xFFFF的代码点,这符合unicode nowdays是20岁的1.0标准。为了在单个数据类型中存储最高可能的unicode代码点,此类型应该有21位但没有这样的类型,所以我们使用32位类型。实际上有一个名为ConvertToUtf32()的静态方法(char类!)就是这样,它可以返回一个低ASCII码点,甚至是最高的unicode码点,后者意味着这个方法可以检测到一个代理对在一个字符串的位置。