'const 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слід використовувати тільки для констант - константи бути значення , які ніколи , ніколи , ніколи НЕ зміниться.
ЛукаХ

3
@LukeH ніколи, ніколи, ніколи не є сильним. Я не можу придумати нічого поганого, що могло б статися, якби оголосити приватний рядок як const і змінити його між двома подіями перекомпіляції.
Бренда Белл

5
@Brenda: Я визнаю, що я використовую private constдля значень, які, власне, не є константами; в основному це неправильне використання constдля цілей мікрооптимізації. Я буду стояти за своїм твердженням "ніколи, ніколи" , навіть якщо це робить мене лицеміром. ;)
ЛукаХ

А як щодо продуктивності у випадку струн зокрема? Чи буде кожне використання const створювати нову копію рядка в пам'яті?
Андрій

@Andrii ні, постійні рядки створюються один раз. Кожне використання матиме однакове посилання в пам'яті.
Мігг

43

Ось хороша розбивка плюсів і мінусів :

Отже, виявляється, що константи слід використовувати, коли малоймовірно, що значення коли-небудь зміниться, або якщо жодні зовнішні програми / libs не будуть використовувати константу. Статичні поля для читання тільки повинні використовуватися, коли потрібен розрахунок часу виконання або якщо зовнішні споживачі є фактором.


19
Дуже цікавий момент із статті - "На високому рівні константи, очевидно, обробляються під час компіляції, тоді як статичні поля для читання лише встановлюються в той момент, коли вони оцінюються під час виконання. Факт, що компілятор встановлює постійні значення. означає, що будь-яка бібліотека / збірка, на яку посилається постійне значення, повинна бути перекомпільована, якщо постійне значення змінюється. Бібліотеки, що посилаються на статичне поле для читання, будуть посилатися на поле, а не на значення, таким чином вони підбирають будь-які зміни в полі без необхідності. для перекомпіляції "
s_hewitt

1
Так, я також прочитав це, і у мене був момент. Я точно цього не знав.
спінон

Ось кешована версія Google: webcache.googleusercontent.com/…
spinon

2
Посилання на посилання більше не доступне.
Саломон Чжан

Це відмінний комплімент відповіді, позначеній як рішення. Визначення використання є дуже корисним. +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 readonlyпроти const, то я б рекомендував static readonlyмайже для всіх випадків, оскільки це більше докази в майбутньому.


Хто це "ОК", про який ви говорите?
Пітер Мортенсен

"Оригінальне запитання"
Бен Астон

0

Ви можете змінити значення static readonly stringлише в staticконструкторі класу або змінному ініціалізаторі, тоді як значення constрядка не можна змінити ніде.


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