Why does Microsoft advise against readonly fields with mutable values?

I agree with you completely, and I do sometimes use readonly in my code for mutable reference types.

As an example: I might have some private or protected member -- say, a List<T> -- which I use within a class's methods in all its mutable glory (calling Add, Remove, etc.). I may simply want to put a safeguard in place to ensure that, no matter what, I am always dealing with the same object. This protects both me and other developers from doing something stupid: namely, assigning the member to a new object.

To me, this is often a preferable alternative to using a property with a private set method. Why? Because readonly means the value cannot be changed after instantiation, even by the base class.

In other words, if I had this:

protected List<T> InternalList { get; private set; }

Then I could still set InternalList = new List<T>(); at any arbitrary point in code in my base class. (This would require a very foolish error on my part, yes; but it would still be possible.)

On the other hand, this:

protected readonly List<T> _internalList;

Makes it unmistakably clear that _internalList can only ever refer to one particular object (the one to which _internalList is set in the constructor).

So I am on your side. The idea that one should refrain from using readonly on a mutable reference type is frustrating to me personally, as it basically presupposes a misunderstanding of the readonly keyword.


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.