Почему resharper предлагает поля только для чтения

Почему ReSharper предлагает поле readonly для 'настроек' в моем примере ниже?

Если я правильно понимаю, вы должны использовать модификатор readonly, если вы изменяете это поле только в конструкторе, но в моем примере я также изменяю его другим методом в том же классе.

Что мне не хватает?

public partial class OptionsForm : Form
{
    private Settings settings;

    public OptionsForm(Settings s)
    {
        settings = s;
    }

    private void SaveData()
    {
        settings.ProjectName = TextBoxProject.Text;
    }
}

Ответ 1

Когда ссылочный тип объявляется как readonly, указатель является неизменным, но не объектом, на который он указывает. Это означает, что:

  • элемент данных ссылочного типа может быть инициализирован, чтобы указать на   экземпляр класса, но как только это будет сделано, это невозможно сделать   укажите другой экземпляр класса вне конструкторов
  • модификатор readonly не влияет на объект, только элемент данных readonly   указывает на.

Прочитайте подробную статью об этом

Отметить элемент данных класса С# как только для чтения, когда его только читать

Ответ 2

Помните, что основной причиной стандартов кодирования и шаблонов проектирования является упрощение для людей понимания вашего кода.

Отметив поле как "readonly", вы рассказывают читателю о классе что они не должны рассматривать как значение поля изменяется.

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

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

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

Ответ 3

ReSharper предлагает сделать "настройки" только для чтения:

readonly private Settings settings;

public OptionsForm(Settings s)
{
    settings = s;
}

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

Если howerver вы должны были предоставить частичный класс или какой-либо другой код в этом классе, который изменил "настройки" , он больше не предполагал бы, что он был только для чтения.

После того как вы только что прочитали, компилятор будет отмечать как предупреждения различные злоупотребления в поле, такие как:

The left-hand side of an assignment must be an l-value

которая является той же ошибкой, которую вы получаете при попытке присвоить значение константе.

также ограничено использование модификаторов параметров ref и out.

Следуя предложению ReSharpers, вы будете предупреждены компилятором, если попытаетесь неправильно использовать поле, которое вы действительно не собираетесь изменять после инициализации.

Ответ 4

Вы не изменяете настройки вне конструктора, объект тот же, что и в SaveData. Свойства объекта могут меняться, но не ссылки на объекты, поэтому, похоже, это имеет смысл с точки зрения Resharper.

Ответ 5

Метод SaveData() не изменяет переменную настроек, она меняет один из ее свойств. Содержимое настроек (к чему это относится) устанавливается только в конструкторе.

Ответ 6

Собственно, вы правы, а Resharper ошибается. Поле следует указывать только для чтения, если оно является неизменным во всей полноте. В вашем примере, если вы сделаете это только для чтения и включите анализ кода Microsoft, он предупредит вас, что настройки имеют изменяемые свойства.

Ответ 7

Это кажется немного странным, я не могу себе представить, что Эрик Липперт и др. не считали очевидным фактом, что создание ссылки неизменяемой не приводит к тому, что экземпляр, на который указывает эта ссылка, неизменен, хотя упомянутый Кодекс Правило анализа поддерживает представление выше (http://msdn.microsoft.com/en-us/library/ms182302 (v = VS.100).aspx).

Это все еще не имеет никакого смысла. Если изменяемые экземпляры не должны быть прочитаны только, то, на мой взгляд, это должна быть ошибка времени компиляции, в противном случае это кажется бессмысленным.

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