В чем разница между const и readonly в C#
Что проверяют
Понимаете ли вы, что const и readonly различаются не синтаксисом, а моментом, когда значение фиксируется: при компиляции или при создании объекта. Следом обычно спрашивают, почему публичная const в библиотеке опасна и чем её заменить.
Как отвечать
const: значение известно компилятору и вшивается прямо в IL каждого места использования. Поле неявно статическое, писать к немуstaticнельзя. Допустимы только встроенные числовые типы,bool,char,string,decimal, перечисления иnullдля ссылочных типов. Затоconstгодится туда, где нужна константа времени компиляции: аргументы атрибутов, меткиcase, значения параметров по умолчанию;readonly: присваивается при объявлении, в конструкторе или вinit-аксессоре, после этого не меняется. Бывает полем экземпляра, тогда у каждого объекта своё значение, илиstatic readonly, тогда значение вычисляется один раз при инициализации типа. Тип любой:DateTime,Guid, коллекция, свой класс;static readonlyвместоconst: правильный выбор для значений, которые могут меняться между версиями.
Главный подводный камень стоит назвать самому: версионирование. Если сборка A объявила public const int Limit = 10, а сборка B её использует, в B окажется литерал 10. Поменяли константу на 20 и пересобрали только A, B продолжит работать с 10. С static readonly сборка B читает поле во время выполнения и увидит новое значение.
Разница в производительности ничтожна: современный JIT подставляет значения static readonly примитивных типов как константы.
Где спотыкаются
Говорят, что readonly делает объект неизменяемым. Нет: неизменяемой становится ссылка, а содержимое readonly List<int> по-прежнему меняется через Add. Для настоящей неизменяемости нужны ImmutableArray или readonly struct.
Путают «значение задаётся в конструкторе» с «значение можно менять в любом методе класса». Присвоить readonly-поле вне конструктора или инициализатора компилятор не даст.
Не могут объяснить, почему нельзя написать const DateTime Start = DateTime.Now. Ответ: значение не вычислимо при компиляции, а DateTime вообще не входит в список типов для const.