Не объявляйте только изменяемые ссылочные типы только для чтения - почему бы и нет?

Я читал этот вопрос и несколько других ответов, и пока я получаю разницу между изменением ссылки и изменением состояния текущего экземпляра, я не почему это означает, что я не должен отмечать его только для чтения. Является ли это потому, что маркирование чего-то, поскольку readonly сообщает компилятору что-то особенное в этом экземпляре, и поэтому оно может затем обрабатывать его как потокобезопасное, если оно действительно не может быть?

Предположительно бывают ситуации, когда я не хочу, чтобы экземпляр мог быть изменен, но не возражайте, если состояние экземпляра изменено (возможно, один синглтон. /me готовится к пламени). Каковы последствия для пометить экземпляр readonly, если я хочу это?

Ответ 1

Нет последствий (для среды выполнения). Компилятор не будет волноваться, ваша среда исполнения не будет взрываться, и все будет нормально.

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

Лично я не согласен с правилом, поэтому я просто отключил его (если вы используете FxCop, и это касается вас).

Ответ 2

Интересная связанная точка: изменчивые структуры readonly - плохая идея из-за ситуаций, подобных этой:

http://ericlippert.com/2008/05/14/mutating-readonly-structs/

Большинство людей, которым я показал этот код, не могут правильно предсказать его вывод.

У Mutable readonly structs есть проблема, что люди думают, что они мутируют их, но на самом деле они мутируют копию.

Обрабатываемые типы readonly ref имеют противоположную проблему. Люди думают, что они глубоко неизменны, но на самом деле они только неглубоко неизменны.

Ответ 3

Я думаю, что дело в том, что это может ввести в заблуждение - неосторожный читатель может предположить, что переменная readonly была фактически константой, которой она не была бы.

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

Ответ 4

Эти два объявления типа являются действительными и полезными, хотя они означают разные вещи:

  • постоянная ссылка на изменяемый объект.
  • изменяемая ссылка на постоянный объект.

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

Необычные читатели, вероятно, тоже необоснованные писатели - не могут много сделать для них:

const SourceRepository cvs = new ReadOnlyRepository(...);

У С++ есть средство принудительного указателя константы на постоянный объект (ссылки на С++ немного отличаются):

Object const* const constantPointerToConstantObject = ...;

Это одна из немногих функций С++, которые я пропускаю на С#/Java.

D имеет еще лучшее ключевое слово (неизменяемое), которое обеспечивает переходную неизменность. D immutable позволяет компилятору сделать вид оптимизации, который вас беспокоит, и гарантировать безопасность. D также имеет const для нетранзитивной константы, что подразумевает, что как транзитивные, так и нетранзитивные формы независимо полезны.