Внутреннее представление строк в C # - PullRequest
5 голосов
/ 24 сентября 2010

Я просто хочу быть уверен:

string x = "";   
char Char = x[0];  // throws exception: "Index was outside the bounds of the array"

Это означает, что строка действительно обрабатывается как массив символов, верно?(По крайней мере, внутри.)

Ответы [ 6 ]

13 голосов
/ 24 сентября 2010

Спецификация языка C # не дает никаких гарантий относительно внутреннего представления строки. Тем не менее, он реализует оператор индекса, чтобы обеспечить символ для каждого символа в строке.

Редактировать: Для пояснения, поскольку несколько человек прокомментировали, да, внутреннее представление System.String в CLR является массивом. Однако спецификация языка ничего не говорит о внутреннем представлении, так что это может (но вряд ли) измениться. Это говорит о том, что строка должна работать как последовательность символов. Единственная информация об этом в спецификации языка находится в разделе 1.3:

Обработка символов и строк в C # использует кодировку Unicode. Тип char представляет кодовую единицу UTF-16, а строковый тип представляет последовательность кодовых единиц UTF-16.

Кроме того, MSDN сообщает:

Строка - это последовательный набор символов Юникода, который используется для представления текста. Объект String - это последовательная коллекция объектов System.Char, представляющих строку. Значением объекта String является содержимое последовательной коллекции, и это значение является неизменным (то есть доступно только для чтения).

Так что в данном случае мы сейчас говорим о CLR, а не о языке. System.String - Однако даже там они не гарантируют массив, только последовательный сбор.

Строка, реализованная со связанным списком и индексатором, который перемещал пробелы на 1022 * вперед в списке, будет достаточной для удовлетворения требований языка. IList<char> также будет соответствовать требованиям, и IList не обязательно будет поддерживаться массивом.

6 голосов
/ 24 сентября 2010

За @JaredPar в других местах на этом сайте :

Подстилающая строка, которую вы создадите, будет также нужен непрерывный блок памяти потому что он представлен в виде массива символов (массивы требуют смежных память).

Я уверен, что вам не следует полагаться на это, поскольку он не является частью интерфейса , но реализация является массивом, если этот оператор верен. Это имеет смысл для меня, учитывая то, что мы знаем о символьных строках и необходимости Microsoft поддерживать эффективное взаимодействие между управляемыми и родными языками.

MSDN говорит только об этом, что не гарантирует, что хранилище является массивом.

Строка представляет собой последовательную коллекцию Символы Юникода, которые используются для представлять текст. Объект String является последовательная коллекция System.Char объекты, которые представляют строку. значение объекта String является содержание последовательной коллекции, и это значение является неизменным (то есть только для чтения).

1 голос
/ 24 сентября 2010

C # это просто язык. Ключевое слово string является псевдонимом для System.String в BCL .Net Framework. Довольно безопасно предположить, что внутренне String - это массив символов. Из MSDN:

Строка - это последовательная коллекция символов Unicode, которая используется для представления текста. Объект String - это последовательная коллекция объектов System.Char, представляющих строку.

1 голос
/ 24 сентября 2010

Насколько я знаю, это правильно. Кстати, вот страница с всем, что вы когда-либо хотели знать о строках :

1 голос
/ 24 сентября 2010

Может оказаться полезным MSDN doc .

В двух словах, строка «сохраняется как последовательная доступная только для чтения коллекция объектов Char»

И, да, к нему можно получить доступ, как к массиву символов. Таким образом, если бы X содержал значение, отличное от String.Empty, то код char Char=X[0;] возвратил бы первый символ строки.

0 голосов
/ 24 сентября 2010

Это зависит от того, что вы подразумеваете под "массивом".

Если вы имеете в виду общую вычислительную концепцию коллекции объектов произвольного доступа с фиксированной длиной и целочисленной индексацией, то да, строку можно считать именно такой. (Общая вычислительная концепция часто включает смежность в памяти, но за исключением нескольких случаев, таких как использование указателей в небезопасном коде, что не очень важно с точки зрения C #).

Если вы имеете в виду реализацию этой концепции на языке C # char[], то не совсем, это разные вещи.

На практике System.String действительно реализован как массив char s, но это не обязательно.

Язык придирки в сторону, практический бит:

Если вы хотите выполнить те же операции со строкой, что и в char[], то это часто будет работать (особенно если строка доступна только для чтения) и очень часто будет наиболее эффективным способом сделать это, пока концептуально довольно просто. В частности, использование foreach и использование индекса, который перемещается между 0 и str.Length - 1, работают хорошо. Точно так же много операций, которые можно выполнить с char[], можно выполнить с string, например, CopyTo() и приведение к IEnumerable<char>.

.

Если вы хотите иметь массив символов, вам нужно вызвать ToCharArray().

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