.NET String.Length属性返回什么?代替中性长度或完整字符长度

Tri*_*nko 23 .net c# string unicode

文档和语言在VS 2008和2010之间有所不同:


VS 2008文档

在内部,文本存储为Char对象的只读集合,每个Char对象代表一个以UTF-16编码的Unicode字符.... 字符串的长度表示字符数,无论字符是否由Unicode代理项对形成.要访问字符串中的各个Unicode代码点,请使用StringInfo对象.- http://msdn.microsoft.com/en-us/library/ms228362%28v=vs.90%29.aspx


VS 2010文档

在内部,文本存储为Char对象的顺序只读集合.... 字符串的Length属性表示它包含的Char对象的数量,而不是Unicode字符的数量.要访问字符串中的各个Unicode代码点,请使用StringInfo对象.- http://msdn.microsoft.com/en-us/library/ms228362%28v=VS.100%29.aspx

两种情况下使用的语言都没有明确区分"字符","Unicode字符","字符类","Unicode代理项对"和"Unicode代码点".

VS2008文档中的语言声明"字符串表示字符数,无论字符是否由Unicode代理项对形成"似乎将"字符"定义为可能是Unicode代理项对的结果的对象,这表明它可能代表一个4字节的序列而不是一个2字节的序列.它还特别指出一个"char"对象以UTF-16编码,这表明它可以代表一个代理对(4个字节而不是2个字节).我很确定这是错的.

VS2010文档更加精确.它区分了"char"和"Unicode character",但不区分"Unicode character"和"Unicode code point".如果代码点引用代理对的一半,并且"Unicode字符"代表完整对,则"Char"类的名称不正确,并且根本不引用"Unicode字符"(他们声明它不),它真的是一个Unicode代码点.

那么以下两个陈述都是真的吗?(是的,我认为.)

  1. String.Length表示Unicode代码点长度,和
  2. String.Length既不表示Unicode字符长度,也不表示我们认为是真正的字符长度(将显示的字符数),而是表示"Char"对象的数量,每个对象代表一个Unicode代码点(不是Unicode字符).

Tri*_*nko 28

String.Length不考虑代理对; 但是,StringInfo.LengthInTextElements方法确实如此.

StringInfo.SubstringByTextElements类似于String.Substring,但它在"Text Elements"上运行,例如代理对和组合字符,以及普通字符.这两种方法的功能都基于StringInfo.ParseCombiningCharacters方法,该方法提取每个文本元素的起始索引并将它们存储在专用数组中.

".NET Framework将文本元素定义为文本单元,显示为单个字符,即字形.文本元素可以是基本字符,代理项对或组合字符序列." - http://msdn.microsoft.com/en-us/library/system.globalization.stringinfo.aspx

  • 纯天才。应该添加一个代码示例,以便人们知道如何获取它。我做了`new StringInfo(str).LengthInTextElements;`。它有效,但我不确定这是最好的选择。 (2认同)

Ana*_*tts 20

String.Length不考虑代理对,它只计算UTF-16字符(即字符总是 2个字节) - 代理对被计为2个字符.

  • 哇.你意识到这意味着什么吗?所有这一次,任何人都有意义使用基本的String和Char类方法编写代码来操作"CHARACTERS"(大写它们,计算它们,交换它们等),它们实际上一直在编写代码来操作"16位块"数据"......并且在遇到基本多语言平面之外的字符时,它们的代码将会断开.难怪软件爆炸,数据变得乱码:( (19认同)
  • 是的.一般来说,UTF16是一个愚蠢的想法(UTF8的所有缺点,但没有任何优点),但它在历史上是我们所坚持的."任何人都应该有64K字符!" (6认同)
  • 无论何时你想操纵Unicode数据,准确的做法是首先将UTF-16(或UTF-8或你正在使用的任何东西)转换为UTF-32,对现在完全解码的Unicode代码点进行修改(s )根据需要,然后转换回UTF-16(或其他). (4认同)
  • 真是一团糟。我喜欢SQL Server足够大胆,可以说将所有内容都拧到BMP之外,因为这些字符非常少见,只需将其称为UCS-2。老实说,如果您不打算在BMP之外支持字符,则最好实现自定义的后备解码器(最佳匹配或替换),以确保您只处理BMP中的内容并消除所有代理对的出现以确保此类数据不会通过不支持它们的应用程序传递。与重写应用程序相比,在应用程序的入口点以这种方式过滤输入的内容更为简单。 (2认同)