Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Microsoft advise against readonly fields with mutable values?

In the Design Guidelines for Developing Class Libraries, Microsoft say:

Do not assign instances of mutable types to read-only fields.

The objects created using a mutable type can be modified after they are created. For example, arrays and most collections are mutable types while Int32, Uri, and String are immutable types. For fields that hold a mutable reference type, the read-only modifier prevents the field value from being overwritten but does not protect the mutable type from modification.

This simply restates the behaviour of readonly without explaining why it's bad to use readonly. The implication appears to be that many people do not understand what "readonly" does and will wrongly expect readonly fields to be deeply immutable. In effect it advises using "readonly" as code documentation indicating deep immutability - despite the fact that the compiler has no way to enforce this - and disallows its use for its normal function: to ensure that the value of the field doesn't change after the object has been constructed.

I feel uneasy with this recommendation to use "readonly" to indicate something other than its normal meaning understood by the compiler. I feel that it encourages people to misunderstand the meaning of "readonly", and furthermore to expect it to mean something that the author of the code might not intend. I feel that it precludes using it in places it could be useful - e.g. to show that some relationship between two mutable objects remains unchanged for the lifetime of one of those objects. The notion of assuming that readers do not understand the meaning of "readonly" also appears to be in contradiction to other advice from Microsoft, such as FxCop's "Do not initialize unnecessarily" rule, which assumes readers of your code to be experts in the language and should know that (for example) bool fields are automatically initialised to false, and stops you from providing the redundancy that shows "yes, this has been consciously set to false; I didn't just forget to initialize it".

So, first and foremost, why do Microsoft advise against use of readonly for references to mutable types? I'd also be interested to know:

  • Do you follow this Design Guideline in all your code?
  • What do you expect when you see "readonly" in a piece of code you didn't write?
like image 900
Weeble Avatar asked May 10 '10 17:05

Weeble


People also ask

What does it mean for a reference type to be mutable?

A mutable type is a type whose instance data can be modified. The System. Text. StringBuilder class is an example of a mutable reference type. It contains members that can change the value of an instance of the class.

How do you make a field immutable in C#?

C# allows creating immutable types by adding readonly keyword to fields or by removing setter from properties. We are obligated then to initialize those readonly members from the constructor or directly in the member's definition.

What is the purpose of readonly modifier in C#?

The readonly modifier prevents the field from being replaced by a different instance of the reference type. However, the modifier doesn't prevent the instance data of the field from being modified through the read-only field.


1 Answers

It seems natural that if a field is readonly, you would expect to not be able to change the value or anything having to do with it. If I knew that Bar was a readonly field of Foo, I could obviously not say

Foo foo = new Foo(); foo.Bar = new Baz(); 

But I can get away with saying

foo.Bar.Name = "Blah"; 

If the object backing Bar is, in fact, mutable. Microsoft is simply recommending against that subtle, counterintuitive behavior by suggesting that readonly fields be backed by immutable objects.

like image 71
Anthony Pegram Avatar answered Oct 08 '22 12:10

Anthony Pegram