'const string' против 'static readonly string' в C #


Ответы:


171

Когда вы используете constстроку, компилятор встраивает значение строки во время компиляции .
Следовательно, если вы используете constзначение в другой сборке, а затем обновите исходную сборку и измените значение, другая сборка не увидит изменения, пока вы ее повторно не скомпилируете .

static readonlyСтрока является нормальным полем , которое получает посмотрело во время выполнения. Следовательно, если значение поля изменяется в другой сборке, изменения будут видны сразу после загрузки сборки без перекомпиляции.

Это также означает, что static readonlyстрока может использовать непостоянные члены, такие как Environment.UserNameили DateTime.Now.ToString(). constСтрока может быть инициализирована только с использованием других констант или литералов.
Также static readonlyстроку можно задать в статическом конструкторе; constстрока может быть инициализирована только в строке.

Обратите внимание, что a static stringможно изменить; вы должны использовать static readonlyвместо этого.


25
+1, И очевидный вывод, с практической и семантической точки зрения: constследует использовать только для констант - константы являются значениями, которые никогда , никогда и никогда не изменяются.
— LukeH

3
@LukeH никогда, никогда, никогда не бывает немного сильным. Я не могу придумать ничего плохого, что могло бы случиться, если бы можно было объявить частную строку как const и изменить ее между двумя событиями перекомпиляции.
— Бренда Белл

5
@Brenda: Я признаю, что использую private constзначения, которые, строго говоря, не являются константами; в основном это неправильное использование constдля целей микрооптимизации. Я буду придерживаться своего заявления «никогда, никогда, никогда» , даже если оно делает меня лицемером. ;)
— LukeH

А как насчет производительности, в частности, струнных? Будет ли каждое использование const создавать новую копию строки в памяти?
— Андрей

@Andrii нет, постоянные строки создаются один раз. Каждое использование будет иметь одну и ту же ссылку в памяти.
— Migg

43

Вот хорошая разбивка плюсов и минусов :

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


19
Очень интересный момент из статьи - «На высоком уровне константы, очевидно, обрабатываются во время компиляции, тогда как статические поля только для чтения устанавливаются во время их оценки во время выполнения. Тот факт, что значения констант заменяются компилятором означает, что любая библиотека / сборка, которая ссылается на постоянное значение, должна быть перекомпилирована, если постоянное значение изменится. Библиотеки, ссылающиеся на статическое поле только для чтения, будут ссылаться на поле, а не на значение, поэтому они будут принимать любые изменения в поле без необходимости для перекомпиляции "
— s_hewitt 06

1
Да, я тоже это читал, и у меня был момент. Я точно этого не знал.
— spinon

Вот это Google кэшированные версии: webcache.googleusercontent.com/...
— спинонных

2
Ссылка на ссылку больше не доступна.
— Salomon Zhang

Это отличное дополнение к ответу, отмеченному как решение. Очень полезно определить использование. +1 от меня.
— Bonez024

11

const

public const string MyStr;

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

static readonly

public static readonly string MyStr;

это время выполнения постоянная. Это означает, что он оценивается при запуске приложения, а не раньше. Вот почему его нельзя использовать в качестве параметра по умолчанию, например, для метода (ошибка компиляции). Хранимое в нем значение можно скрыть.


6

OQ спросил о static stringпротив const. Оба имеют разные варианты использования (хотя оба считаются статическими).

Используйте const только для действительно постоянных значений (например, скорости света - но даже это зависит от среды). Причина этого строгого правила заключается в том, что значение const заменяется на использование const в сборках, которые на него ссылаются, что означает, что у вас могут возникнуть проблемы с версией, если const изменится в месте определения (т.е. она не должна была быть константой после всего). Обратите внимание, что это даже влияет на private constполя, потому что у вас могут быть базовый класс и подкласс в разных сборках, а частные поля наследуются .

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

Если вы имели в виду static readonlyvs const, я бы порекомендовал static readonlyпочти для всех случаев, потому что это больше подходит для будущего.


О ком вы говорите "OQ"?
— Питер Мортенсен

«Оригинальный вопрос»
— Бен Астон

0

Вы можете изменить значение a static readonly stringтолько в staticконструкторе класса или инициализаторе переменной, тогда как вы не можете нигде изменить значение constстроки.


2
Я не понимаю, как это добавляет что-либо помимо того, что уже сказано в существующих ответах.
— Иск Фонда Моники,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.