Что возвращает свойство .NET String.Length? Суррогатная нейтральная длина или полная длина символа - PullRequest
23 голосов
/ 14 апреля 2011

Документация и язык варьируются между VS 2008 и 2010:


VS 2008 Документация

Внутри текст хранится как коллекция только для чтения объектов Char, каждый из которых представляет один символ Unicode, закодированный в UTF-16 . ... Длина строки представляет количество символов независимо от того, сформированы они из суррогатных пар 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», «классом Char», «суррогатной парой Unicode» и «кодовой точкой Unicode».

Язык в документации к VS2008, в котором говорится, что «строка представляет количество символов независимо от того, сформированы ли символы из суррогатных пар Unicode или нет« кажется, что определяет » символ "как объект, который может быть результатом суррогатной пары Unicode, что предполагает, что она может представлять 4-байтовую последовательность, а не 2-байтовую последовательность. В начале также конкретно указывается, что объект "char" закодирован в UTF-16, что предполагает, что он может представлять суррогатную пару (4 байта вместо 2). Я вполне уверен, что это неправильно.

Документация VS2010 немного более точна. Он проводит различие между «char» и «Unicode-символом», но не между «Unicode-символом» и «Unicode code point». Если кодовая точка относится к половине суррогатной пары, а «символ Unicode» представляет собой полную пару, то класс «Char» назван неправильно и вообще не ссылается на «символ Unicode» (что, как они утверждают, делает нет), и это действительно код Unicode.

Так верно ли оба следующих утверждения? (Да, я думаю.)

  1. String.Length представляет длину кодовой точки Unicode, а
  2. String.Length не представляет ни длину символа Unicode, ни то, что мы считаем истинной длиной символа (количество отображаемых символов), а скорее количество объектов "Char", каждый из которых представляет кодовую точку Unicode. (не символ Юникода).

Ответы [ 3 ]

27 голосов
/ 20 января 2012

String.Length не учитывает суррогатные пары; однако метод StringInfo.LengthInTextElements делает.

StringInfo.SubstringByTextElements аналогично String.Substring, но работает с «текстовыми элементами», такими как суррогатные пары и символы объединения, а также обычные символы. Функциональность обоих этих методов основана на методе StringInfo.ParseCombiningCharacters, который извлекает начальный индекс каждого текстового элемента и сохраняет их в частном массиве.

".NET Framework определяет текстовый элемент как единицу текста, которая отображается как один символ, то есть графема. Текстовый элемент может быть базовым персонажем, суррогатной парой или комбинированным персонажем последовательность. "- http://msdn.microsoft.com/en-us/library/system.globalization.stringinfo.aspx

20 голосов
/ 14 апреля 2011

String.Length не учитывает суррогатные пары, он учитывает только символы UTF-16 (т. Е. Символы всегда 2 байта) - суррогатные пары считаются 2 символами.

1 голос
/ 04 июля 2013

Оба я бы посчитал ложным.Второй вопрос будет верным, если вы спросите о количестве кодовых точек Юникода, но спросите о «длине».Длина строки - это количество ее элементов, которые являются словами.На случай, если в строке есть только кодовые точки Юникода из BMP (базовой многоязычной плоскости), длина равна количеству символов / кодов Юникода.Если существуют кодовые точки из-за BMP или суррогатов-сирот (суррогаты высокого или низкого уровня, которые не отображаются в виде упорядоченной пары), длина НЕ равна числу символов / кодовых точек.

Прежде всего,Строка - это набор слов, список слов, массив слов или поток слов.Его содержание - 16-битные слова и все.Называть элемент "char" или "wchar" грех в отношении символов Юникода.Поскольку у символа юникода может быть кодовая точка больше 0xFFFF, он не может быть сохранен в типе шириной 16 битов, и если этот тип называется char или wchar, это еще хуже, потому что он может содержать только кодовые точки, ограниченные 0xFFFF, что соответствует юникоду1.0 стандарт, которому сегодня 20 лет.Чтобы хранить даже максимально возможную кодовую точку Юникода в одном типе данных, этот тип должен иметь 21 бит, но такого типа нет, поэтому мы должны использовать 32-битный тип.Фактически существует статический метод (класса char!) С именем ConvertToUtf32 (), который делает именно это, он может возвращать низкую кодовую точку ASCII или даже самую высокую кодовую точку Unicode, в результате чего последний подразумевает, что этот метод может обнаружить суррогатную парув позиции String.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...