![image](https://habrastorage.org/files/c9d/b0b/d1b/c9db0bd1b6374cd1b14a449f14b02086.jpg)
«Константы помещаются в метаданные сборки, поэтому если были изменения, нужно перекомпилировать все использующие ее сборки. Т.к. DLL с константой может даже не загружаться.»
Да ладно, подумал я, и полез ставить эксперименты. Создал проект TestConstants, в нем класс,
public class Master
{
public const string Const = "Hello world";
}
затем проект TestConstantsSlave,
static void Main()
{
Console.WriteLine(Master.Const);
Console.ReadKey();
}
Заменил константу на “Hello habr”, перебилдил основной проект, запустил по F5…
На консоли высветился “Hello habr”. Видимо, студия ребилднула заодно и Slave проект. В принципе, на этом можно было успокоиться, но хотелось немного поэкспериментировать.
Первым делом я заменил константу на “Greetings, sir von Neumann”, ребилднул основной проект, и запустил Slave через проводник → TestConstantsSlave.exe. На консоли светилось «Hello habr», да простит меня великий Нейман. Скопировал свежую библиотеку к Slave – по прежнему «Hello habr”. Удалил TestConstants библиотеку — снова “Hello habr”.
Неужели действительно константа копируется в метаданные? Открываем ildasm. В манифесте Slave все стандартно: версия, заголовки, токены. Константы нет (что разумно). Пробежал по классам — никаких метаданных в явном виде не обнаружено.
Зато в коде Slave есть «Hello habr» в явном виде.
![ildasm](https://habrastorage.org/files/0e2/686/3b1/0e26863b151f49d3873f9ae437b08e0a.jpg)
Смотрим описание инструкции ldstr на msdn. “Pushes a new object reference to a string literal stored in the metadata“. Видимо, метаданные скрыты для ildasm. На всякий случай проверил dotPeek – результат аналогичен (зато видно, что Slave проект не ссылается на TestConstants).
Проверка константы другого типа: использование Int32 константы дает другой il код: ldc.i4.5. Здесь у нас простой пуш инта в стек (что опять-таки разумно — строки длинные, есть смысл их кэшировать, а вот накладные расходы на вытягивание инта из кэша перевешивают выхлоп). Видимо, в изначальной статье и msdn под метаданными подразумевается часть механизма интернирования строк (тунц, тынц), что, кстати, объясняет отсутствие метаданных в ildasm — пул строк генерируется для процесса.
И что дальше?
Ничего страшного. Студия же правильно билдит, да и константы меняются не каждый день. С другой стороны, я уже работал с проектом, где SDK и использующие его утилиты находились в разных солюшнах, и обновление SDK могло породить «баг неизменной константы».
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Встречались ли вы с «багом неизменной константы»?
13.48% Да36
86.52% Нет231
Проголосовали 267 пользователей. Воздержались 97 пользователей.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Стоит ли расследовать детали работы nameof()?
79.58% Да191
20.42% Нет49
Проголосовали 240 пользователей. Воздержались 111 пользователей.