Ни модификаторы readonly
, ни volatile
не являются проникающими. Они применяются к самой ссылке, а не к свойствам объекта.
Ключевое слово readonly
утверждает - и обеспечивает - что переменная не может измениться после инициализации. Переменная - это небольшой кусок памяти, в котором хранится ссылка.
Ключевое слово volatile
сообщает компилятору, что содержимое переменной может быть изменено несколькими потоками. Это препятствует использованию компилятором оптимизаций (таких как считывание значения переменной в регистр и использование этого значения в нескольких инструкциях), которые могут вызвать проблемы с одновременным доступом. Опять же, это влияет только на небольшой кусок памяти, где хранится ссылка.
При применении этого способа вы можете видеть, что они действительно взаимоисключающие. Если что-то доступно только для чтения (может быть записано только один раз, при инициализации или построении), то оно также не может быть изменчивым (может быть записано в любое время несколькими потоками).
Что касается вашей озабоченности проблемами кэширования, то в IIRC существуют довольно строгие правила, когда компилятор может кэшировать результат вызова свойства. Имейте в виду, что является вызовом метода, и это довольно сложная оптимизация (с точки зрения компилятора) для кэширования его значения и пропуска его вызова. Я не думаю, что это то, что вам нужно беспокоиться слишком много.