Почему 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).
Это все еще не имеет никакого смысла. Если изменяемые экземпляры не должны быть прочитаны только, то, на мой взгляд, это должна быть ошибка времени компиляции, в противном случае это кажется бессмысленным.
Я вижу, как использовать ссылку неизменяемую, а не экземпляр, на который он указывает.