Почему не String.Empty константа?

В .Net почему String.Empty читается только вместо константы? Мне просто интересно, знает ли кто-нибудь, что аргументировало это решение.

Причина, по которой static readonly используется вместо const заключается в использовании с неуправляемым кодом, как указано Microsoft здесь в выпуске Common Language Infrastructure 2.0 Release . Файл для просмотра – sscli20\clr\src\bcl\system\string.cs .

Пустая константа содержит пустое строковое значение. Нам нужно вызвать конструктор String, чтобы компилятор не отмечал это как литерал.

Пометить это как литерал означает, что он не отображается как поле, к которому мы можем получить доступ из native.

Я нашел эту информацию из этой удобной статьи в CodeProject .

Я думаю, что здесь много путаницы и плохих ответов.

Прежде всего, const поля являются static членами ( не членами экземпляра ).

Проверьте раздел 10.4 Константы спецификации языка C #.

Несмотря на то, что константы считаются статическими членами, декларация констант не требует и не допускает статического модификатора.

Если члены public const являются статическими, нельзя считать, что константа создаст новый объект.

Учитывая это, следующие строки кода делают то же самое в отношении создания нового объекта.

 public static readonly string Empty = ""; public const string Empty = ""; 

Вот примечание от Microsoft, объясняющее разницу между 2:

Ключевое слово readonly отличается от ключевого слова const. Поле const может быть инициализировано только при объявлении поля. Поле readonly может быть инициализировано либо в объявлении, либо в конструкторе. Поэтому поля readonly могут иметь разные значения в зависимости от используемого конструктора. Кроме того, в то время как константное поле является константой времени компиляции, поле readonly может использоваться для констант времени выполнения, …

Поэтому я считаю, что единственным правдоподобным ответом здесь является Джефф Йейтс.

 String.Empty read only instead of a constant? 

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

Если вы оставите строку только на одном месте, так как это String.Empty , программа сохранит одну и ту же строку только на одном месте и прочитает ее или ссылается на нее – сохранение данных в памяти минимально.

Кроме того, если вы скомпилируете любую DLL с помощью String.Empty as const и по какой-либо причине измените String.Empty, то скомпилированная dll не будет работать более точно так же, потому что cost делает внутренний код фактически хранить копию строка для каждого вызова.

См. Этот код, например:

 public class OneName { const string cConst = "constant string"; static string cStatic = "static string"; readonly string cReadOnly = "read only string"; protected void Fun() { string cAddThemAll ; cAddThemAll = cConst; cAddThemAll = cStatic ; cAddThemAll = cReadOnly; } } 

будет получен компилятором как:

 public class OneName { // note that the const exist also here ! private const string cConst = "constant string"; private readonly string cReadOnly; private static string cStatic; static OneName() { cStatic = "static string"; } public OneName() { this.cReadOnly = "read only string"; } protected void Fun() { string cAddThemAll ; // look here, will replace the const string everywhere is finds it. cAddThemAll = "constant string"; cAddThemAll = cStatic; // but the read only will only get it from "one place". cAddThemAll = this.cReadOnly; } } 

и вызов сборки

  cAddThemAll = cConst; 0000003e mov eax,dword ptr ds:[09379C0Ch] 00000044 mov dword ptr [ebp-44h],eax cAddThemAll = cStatic ; 00000047 mov eax,dword ptr ds:[094E8C44h] 0000004c mov dword ptr [ebp-44h],eax cAddThemAll = cReadOnly; 0000004f mov eax,dword ptr [ebp-3Ch] 00000052 mov eax,dword ptr [eax+0000017Ch] 00000058 mov dword ptr [ebp-44h],eax 

Изменить: Исправлена ​​опечатка

Этот ответ существует для исторических целей.

Первоначально:

Поскольку String является classом и поэтому не может быть константой.

Расширенный поиск:

Много полезного диалога было забито при проверке этого ответа, и вместо его удаления этот контент воспроизводится напрямую:

В .NET (в отличие от Java) строка и String точно такие же. И да, у вас могут быть строковые литерал-константы в .NET. DrJokepu 3 февраля 2009 в 16:57

Вы говорите, что class не может иметь константы? #: 3159 StingyJack

Да, объекты должны использовать readonly. Только структуры могут выполнять константы. Я думаю, что когда вы используете string вместо String компилятор изменяет const в readonly для вас. Все, что нужно сделать, чтобы C программисты остались довольны. #: 3459 Garry Shutler

tvanfosson просто объяснил это немного более многословным. «X не может быть константой, потому что содержащее Y является classом» было просто немного без контекста;) Leonidas

string.Empty – это статическое свойство, которое возвращает экземпляр classа String, а именно пустую строку, а не сам class строки. #: 23912 tvanfosson

Пусто – это экземпляр readonly (это не свойство) classа String. #: 17999 senfo senfo

Голова болит. Я все еще думаю, что я прав, но теперь я менее уверен. Исследования нужны сегодня! #: 3459 Garry Shutler

Пустая строка – это экземпляр classа string. Пусто – это статическое поле (не свойство, которое я исправляю) в classе String. В основном разница между указателем и тем, на что он указывает. Если бы не было readonly, мы могли бы изменить, к какому экземпляру относится пустое поле. Tvanfosson tvanfosson # 3

Гарри, тебе не нужно делать никаких исследований. Думаю об этом. Строка – это class. Пустой экземпляр строки. #: 17399 senfo senfo в 17:12

Есть кое-что, что я не совсем понимаю: как можно построить статический конструктор classа String экземпляр classа String? Разве это не какой-то сценарий «курица или яйцо»? #: 3459 DrJokepu

Этот ответ будет правильным для любого другого classа, но System.String. .NET делает очень много специальных функций для строк, и один из них состоит в том, что вы можете иметь строковые константы, просто попробуйте. В этом случае Джефф Йейтс имеет правильный ответ. #: 3059 Joel Mueller Joel Mueller

Как описано в п. 7.18, константное выражение является выражением, которое может быть полностью оценено во время компиляции. Поскольку единственным способом создания ненулевого значения ссылочного типа, отличного от строки, является применение нового оператора, и поскольку новый оператор не допускается в константном выражении, единственное возможное значение для констант ссылочных типов кроме строки, равно null. Предыдущие два комментария были взяты непосредственно из спецификации языка C # и повторили то, что упоминал Джоэл Мюллер. #: 17999 senfo senfo 5

  • Попытка вызвать Sub с помощью String - VBA
  • Как поместить переменную внутри строки в Python?
  • Фиксирование Sublime Text 2 окончания строки?
  • Как получить имя переменной в виде строки?
  • Давайте будем гением компьютера.