当前位置: 首页 > 编程语言 > C#

不可变的只读引用类型和FXCop违规:不要声明只读可变引用类型分享

时间:2023-04-10 18:48:11 C#

C#学习教程:不可变只读引用类型和FXCop违规:不声明只读可变引用类型DoNotDeclareReadOnlyMutableReferenceTypes"MSDN:http://msdn.microsoft.com/en-us/library/ms182302%28VS.80%29.aspx导致此违规的MSDN代码:namespaceSecurityLibrary{publicclassMutableReferenceTypes{staticprotectedreadonlyStringBuilderSomeStringBuilder;静态MutableReferenceTypes(){SomeStringBuilder=newStringBuilder();从乔恩在这里和这里的回答中,我了解到保存对象引用的字段(在本例中为SomeStringBuilder)是只读的,而不是对象本身(由newStringBuilder()创建)所以以这个例子为例,我将如何更改一旦字段引用对象本身?我喜欢EricLippert关于如何更改只读数组的示例,并希望看到类似于任何其他可变引用类型的内容由于问题中出现了MutableReferenceTypes类,因此SomeStringBuilder字段是私有的,因此实际上不能从任何外部调用者更改它。但是,类本身可以更改字段。目前没有,但它可能会在未来的迭代中。这是一个示例方法:publicstaticvoidMutate(){SomeStringBuilder.AppendLine("Foo");}调用Mutate方法会改变类,因为SomeStringBuilder现在已经改变。不变性不仅仅与代码的当前版本有关,还与保护自己免受未来错误的影响有关。并非所有类都需要是不可变的,但如果您选择创建不可变类型,那么保持一致是最安全的。readonly意味着您不能在构建后更改引用。FXCop的官方立场是建议只将那些不能修改的类型声明为只读。所以像字符串这样的东西是可以的,因为对象的值不能改变。但是,StringBuilder的值可以更改,但它是只读的,它只会阻止您将字段分配给不同的StringBuilder实例,或者在构造函数运行后为null。我不同意FXCop对这条规则的看法。只要有人明白这只是一种强制执行,引用在构建后可能不会改变,那么就不会混淆。请注意,值类型通过readonly关键字变得不可变,但引用类型不是。命名空间SecurityLibrary{公共类MutableReferenceTypes{staticprotectedreadonlyStringBuilderSomeStringBuilder;staticMutableReferenceTypes(){//允许SomeStringBuilder=newStringBuilder();}voidFoo(){//不允许SomeStringBuilder=newStringBuilder();}voidBar(){//允许但FXCop不喜欢这个SomeStringBuilder.AppendLine("Bar");}}}.Net有一个允许的不可变引用类型列表,StringBuilder不是其中之一。抱怨是你正在构建的东西不是不可变的,尽管静态构造函数被调用一次并且类被初始化一次,所有这些都保持不变,其余的是可变的。一个线程可以调用.Append(),然后是另一个……您会看到字符串生成器本身是如何发生变化的,并且实际上并不是只读的,因为它不断改变状态/发生变化。将readonly声明为true是用词不当,因为那里引用的对象本身在不断变化。您无法更改引用,但对(可变)对象的任何调用都会更改其状态。因此,由于SomeStringBuilder(在这种情况下)本身是可变的,它的内容可能会改变,这可能会误导该类的用户,因为它实际上不是“只读的”。基本上,只读不以任何方式保证对象不会改变,它只是说引用不会改变。您不会更改对象的值。这就是规则的重点。任何声明为只读的字段都应该是只读的。拥有只读可变引用是自相矛盾的。如果您可以更改字段“指向”的值,那么它就不再是真正的只读了。将某个对象A的所有成员的值赋给某个??字段表示的某个对象B,或者只是将A赋给字段(当它们是同一类型时),这两者在功能上确实没有区别,但是当字段在只有一个是有效只读的,但是因为你可以有效地改变字段所代表的值的值,正如已经声明的那样,它并不是真正的只读。以上就是C#学习教程:不可变只读引用类型与FXCopViolation:Donotdeclareallthecontentsharedbytheread-onlyvariablereferencetype。如果对大家有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: