Brad Abrams talks about mutable read-only fields and I attempt to elaborate.
Brad Abrams posts an article on Mutable reference types should not be read-only fields.
You really have to think about what this means. In the example he creates a new type, say F, that has some internal data. On another type, he creates a read-only field of type F. He then demonstrates, how you can change values on say F, even though the field is marked using read-only. I don't think the rule here is that you shouldn't do this, just that you should be aware of the ramifications of what you are doing. In other words, are you expecting that the full type structure and data represented by F be completely immutable, or are you just wanting to make sure that the object reference isn't changed. Most users don't draw a difference between the two and expect read-only to provide the protection level of option 1, that the type is now completely immutable.
It isn't easy to make an immutable reference type in .NET. Array's aren't immutable per say because you can always change the elements. Hell, collections are only pseudo-immutable using a special encapsulation method that turns say an ArrayList into a ReadOnlyArrayList. You can check this out in Rotor. The basic premise is that the original ArrayList is stored as a member variable and any access of the ArrayList now goes through the virtual overrides provided by the read-only collection class. This only partially works, because while a ReadOnlyArrayList make not allow you to mess with the original collection, you can still erroneously make direct calls (using call instead of callvirt) to the ArrayList implementation. You see, the ReadOnlyArrayList is actually two ArrayList's. It stores the original ArrayList, but still maintains all of the underlying data structure to itself be an ArrayList. How hacky is that? There just isn't any immutability there per say.
What are the other options though? An immutable flag would do. A basic bool. But that means every time you access a method you need to check for immutability and throw the appropriate exceptions. This immutable flag in the case of ArrayList could actually be a member field for isReadOnly.
We used the immutable flag in the Terrarium quite a bit. There are loads of locations where we need to work with a type within the game engine and change state variables. Then when it comes time to give it to the creatures, we can't allow things to be changed. This quickly turns into a nightmare, since every complex type that is part of the immutable type also has to be immutable. You can see this with our AntennaState class. We actually had to cascade an immutable flag down the hierarchy so all classes knew not to change their underlying data.
Any other ways to make things immutable? Well, I've recently been playing with delegates. They seem to provide the ability to make something immutable. You can have two functions, one for the immutable case and one for the mutable case. Then simply remap the delegate to the appropriate function depending on the state of the class. Kind of hurts properties though right? Probably has some negative class hierarchy/virtual/override issues. In some cases it makes sense (my new ImageFast implementation actually sets up which method to call, the custom PInvoke or the actual Image.FromFile, depending on the current level of security provided to the user) since you can use it to modify code-paths transparently, but I'm not sure it solves immutability properly.
While I think the FXCop rule is helpful in detailing that there is a potential problem, once the rule flags, there is a great deal more work to be done to decide if there is truly going to be a problem and how you are going to fix that. Everyone has their own methods for doing immutability in .NET and the right one has to be chosen. I personally like the immutability flag, but it is more work and imposes possible speed issues. I'm starting to like the delegate replacement technique more and more, and maybe I'll spend some time talking about that when I'm done with the ImageFast class.