
[英]Why does resharper suggests using readonly in fields that are not changed?
[英]Why does resharper suggest readonly fields
为什么ReSharper在下面的示例中建议“设置”的只读字段?
如果我理解正确,如果仅在构造函数中更改此字段,则应使用readonly
修饰符,但在我的示例中,我也在同一个类中的另一个方法中更改它。
我错过了什么?
public partial class OptionsForm : Form
{
private Settings settings;
public OptionsForm(Settings s)
{
settings = s;
}
private void SaveData()
{
settings.ProjectName = TextBoxProject.Text;
}
}
当引用类型声明为readonly时,指针是不可变的,但不是它指向的对象。 这意味着:
- 可以初始化引用类型数据成员以指向类的实例,但是一旦完成,就不可能使它指向构造函数之外的类的另一个实例
- readonly修饰符对readonly数据成员指向的对象没有影响。
阅读详细的文章
请记住,编码标准和设计模式的主要原因是让人们更容易理解您的代码。
通过将字段标记为“只读”,您告诉该类的读者他们不需要考虑字段的值如何更改。
然而,由于只读字段指向的对象可以使其状态发生变化,因此将字段标记为只读可能会产生误导。 因此,考虑一下天气,它可以帮助您的代码的读者(例如一个人) 了解您的设计。
如果字段指向的对象中的值在对象生存期内发生变化,那么我认为字段不应该标记为只读。 (例如,指向的对象应该表现得好像在您的类上的承包商被调用时它是不可变的)
(但是有一些例外,例如,即使记录器确实更改了日志文件的状态,也可以使用只读字段指向记录器。)
ReSharper建议只读“设置”:
readonly private Settings settings;
public OptionsForm(Settings s)
{
settings = s;
}
因为,在扫描您的代码时,它得出结论,您的“设置”字段仅出现在同一个类的构造函数中。
如果你要在这个类中提供修改“设置”的部分类或其他代码,那么它将不再表示它是readonly。
一旦标记为只读,编译器将标记为警告各种字段的滥用,例如:
The left-hand side of an assignment must be an l-value
当您尝试将值分配给常量时,会出现同样的错误。
ref和out参数修饰符的使用也是有限的。
通过遵循ReSharpers建议,如果您尝试滥用在初始化后确实不打算更改的字段,编译器将会发出警告。
您没有更改构造函数之外的设置,该对象与SaveData中的对象相同。 对象属性可能正在改变,但不是对象引用,因此从Resharper角度来看似乎有意义。
SaveData()方法不会更改设置变量,它会更改其属性。 设置的内容(它引用的内容)仅在构造函数中设置。
实际上,你是对的,Resharper是错的。 如果字段完全不可变,则只应标记为只读字段。 在您的示例中,如果您只读它并启用Microsoft的代码分析,它将警告您Settings具有可变属性。
这似乎有点奇怪,我无法想象Eric Lippert等人没有考虑这样一个显而易见的事实,即引用不可变引用不会使引用不可变引用实例,尽管提到的代码分析规则确实如此。支持上述观点(http://msdn.microsoft.com/en-us/library/ms182302(v=VS.100).aspx)。
它仍然没有任何意义。 如果可变实例不应该是readonly,那么,在我看来,它应该是一个编译时错误,否则看起来毫无意义。
我可以看到使用引用不可变,而不是它指向的实例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.