Что такое внутренний формат строки.NET?
Я делаю какой-то довольно интенсивный код для работы со строками в C#.NET, и мне стало интересно узнать о некоторых статьях Джоэла Спольски, которые я вспомнил, читая некоторое время назад:
http://www.joelonsoftware.com/articles/fog0000000319.html
http://www.joelonsoftware.com/articles/Unicode.html
Итак, как.NET это делает? Два байта на символ? Есть несколько символов Юникода ^ H ^ H ^ H ^ H ^ H, которые нуждаются в большем. И как кодируется длина?
2 ответа
Перед тем, как появится Джон Скит, есть ссылка на его отличный блог о строках в 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 без каких-либо параметров фактически создает объект UnicodeEncoding, используя порядок байтов с прямым порядком байтов. Класс UnicodeEncoding (который реализует кодировку UTF-16) также может обрабатывать прямой порядок байтов (также поддерживает обработку метки порядка байтов). Собственный порядок байтов платформы Intel является прямым порядком байтов, поэтому для.NET (и Windows), вероятно, более эффективно хранить строки Unicode в этом формате.