Есть ли какая-то другая причина помимо производительности и читаемости того, почему System.String является ссылочным типом, а не типом значения? - PullRequest
8 голосов
/ 25 июня 2010

Почему String был разработан как ссылочный тип, а не тип значения?

С точки зрения моделирования я бы смоделировал его как тип значения, поскольку он представляет что-то без идентичности. У него нет отличительных признаков. (Например, я не могу различить одну строку "a" и другую строку "a")

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

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

Ответы [ 6 ]

5 голосов
/ 25 июня 2010

Как вы указали, иметь тип значения, который может стать очень большим, может быть непомерно из-за ограниченного пространства в стеке и семантики копирования при использовании типов значений.

Кроме того, способ реализации строк в .NET добавляет пару элементов в уравнение. Строки являются не только ссылочными типами, они также являются неизменяемыми (в любом случае, вне пространства имен System), и среда выполнения использует интернирование, чтобы делать аккуратные трюки для строк.

Все это добавляет пару преимуществ: повторяющиеся литеральные строки хранятся только один раз, и сравнение таких строк становится чрезвычайно эффективным, поскольку вы можете сравнивать ссылки вместо потоков символов Unicode. Эти параметры не будут возможны для типов значений.

2 голосов
/ 25 июня 2010

Структуры необходимо фиксированного размера.Подумайте о string[], например.Единственный способ получить string в качестве значения-типа - сохранить только указатель.Что является по существу тем, что мы достигаем, используя ссылочный тип.

Конечно, это также чрезвычайно полезно, что мы не копируем строку каждый раз, когда мыназначьте его.

1 голос
/ 25 июня 2010

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

1 голос
/ 25 июня 2010

Насколько я понимаю, строки являются неизменяемыми классами, а не структурами только для повышения производительности.

Строки, как правило, создаются, а затем передаются многим объектам для рендеринга пользователю или передачи другим системам.После их создания строки, как правило, не изменяются, поэтому копирование всего массива символов как уникального значения в каждом объекте имеет небольшое практическое значение и создает много временных объектов.

0 голосов
/ 25 июня 2010

С точки зрения равенства, у вас все еще есть возможность рассматривать его как тип значения с == оператор.

Так что, если что-нибудь, это просто и выгодно иметь его в качестве ссылки нет?

0 голосов
/ 25 июня 2010

  • ~ Отредактировано для более точного ответа на вопрос

Один момент заключается в том, что тип String, как и во многих языках, кодируется как Unicode, и поэтому нелогично рассматривать их как примитивные типы (например, int), поскольку нет прямого соответствия между его двоичным кодированием и его формой для чтения человеком.

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

Причина того, что примитивные переменные могут находиться в стеке, заключается в том, что для большого числа номеров достаточно места. Это не относится к более типу данных String.

Типы операций, выполняемых со строками, на самом деле не арифметические, а основаны на булевой логике (кроме случаев подсчета строк, когда они обрабатываются как вектор или массив), поэтому имеет смысл оптимизировать структуру данных для ее первичного использования, через пространство имен System.String.

...