Я полагаю, вы спрашиваете, как бы вы реализовали строковый объект.
Из соображений производительности вы хотели бы сохранить память, выделенную для символов в строке, как один блок. Это ускорит операции, выполняемые со всеми элементами: изменение регистра, копирование, вычисление длины, indexof и т. Д. Это также облегчит реализацию операций, которые работают с началом или концом строки - обрезка, подстрока и т. Д.
Существуют определенные операции, в которых структура данных, такая как связанный список, облегчит реализацию, например вставка или удаление символа / подстроки. Однако, учитывая отношение объема служебной памяти, необходимой для поддержания такой структуры данных, к средней длине строки, стоимость перевешивает любые потенциальные выгоды.
Должна ли строка быть неизменной или нет, продиктовано двумя соображениями:
- вы предоставляете прямой доступ к памяти или все операции инкапсулированы в классе?
- Ваше распределение памяти управляется средой выполнения или вам нужно управлять этим самостоятельно?
Традиционный подход C ++ - предоставить прямой доступ к базовой памяти к коду, который использует строковый объект. Это имеет большой смысл, так как память в любом случае выделяется и управляется клиентским кодом, поэтому предоставление прямого доступа к нему обеспечивает наилучшую производительность. Недостатком является то, что любая операция, которая изменяет длину строки, обычно приводит к перераспределению памяти. Существуют умные строковые классы, которые управляют собственным диспетчером памяти для решения этой проблемы, например CString ATL.
Подход C # состоит в том, чтобы инкапсулировать базовую память в объекте и сделать строку неизменной. Это позволяет CLR управлять памятью, а объекты собирать мусор по тем же правилам, которые применяются к любому другому объекту. Из-за этого существует небольшая штрафная плата, но преимущества упрощенного использования и возможности предлагать стабильную реализацию довольно сложных операций перевешивают стоимость выполнения. Кроме того, есть сопутствующий класс StringBuilder, который предлагает некоторые преимущества прямого доступа к памяти, предварительно выделяя больший буфер и изменяя экземпляр в нем, пока он не будет завершен с экземпляром String.