Mutable reference types should not be read-only fields

On the internal FxCop support alias someone asked about the background on the rule that mutable reference types should not be read-only fields… One of the more astute members of the alias was able to quote chapter and verse of the Design Guidelines where it is explained in more detail…   


I thought I would share it with you as it is an important and interesting guideline…


            Do not return mutable types from readonly fields.  A mutable type is a type whose instance data can be modified (notice arrays and most collections are mutable types). The read-only modifier on a reference type field prevents the field from being replaced by a different instance of the reference type but does not prevent the field's instance data from being modified through the reference type.[1]
The following example shows how it is possible to change the value of a readonly field.

using System;


public class F {

   int i;

   public void Change () {



   public void Print () {

      Console.WriteLine (i);




public class Bar {

    public static readonly F f = new F ();


public class Foo {

   public static void Main () {









[1] Covered by FxCop rule: MutableReferenceTypesShouldNotBeReadOnly

Comments (13)

  1. Wesner Moise says:

    Now, would this rule apply also to get only properties.

    I don’t see any real difference between get-only properties and readonly fields, except in the case thatwhen the readonly field is a large valuetype. In that case, one can modify the properties of the readonly field directly, where properties of properties (which return valuetypes) cannot be modified. In addition, access to the readonly field is faster because the JIT compiler doesn’t inline on structs.

    Actually, I can see where a readonly field could be mutable. In some case, a class has maintains its own instance of some mutable reference type. The class wants to expose that instance that it owns to the outside world and subject it to external modification, but it does not want the reference to be changed.

  2. Craig Eddy says:

    Call me dense, I’m sure I’m missing something, but…

    The example shown does not change the value of a read-only field. The REFERENCE to an instance of F is never modified (that’s what’s returned by Bar.f). An internal member of F is modified.

  3. Craig, you aren’t dense. That is exactly what is happening. That is what they mean by Mutable in the case above. The internal representation of the type can be changed but the reference cannot. I’m not sure what people expect from readonly, but I think the rule is based on common expectations that aren’t upheld rather than the idea there is an actual bug or true underlying issue. Take the following code:

    public class Foo {

    private int member = 0;

    public int Member { get { return member; } set { member = value; } }


    public class Bar {

    public static readonly Foo F = new Foo();


    public class Baz {

    public static Foo F = new Foo();


    public class Runner {

    private static void Main() {

    Foo myWorkingFoo = Bar.F;

    myWorkingFoo.Member = 20;

    myWorkingFoo = Baz.F;

    Baz.F = new Foo();

    myWorkingFoo.Member = 20;



    Above is the situation a read-only reference variable is actually supposed to be solving. If I want to take a local reference, and modify it, then I’m guaranteed that it won’t be shaken from underneath the carpets. You see, when taking myWorkingFoo off of Bar, I am guaranteed that once I store the reference, all changes I make will happen to Bar.F. With Baz.F, after taking the local reference, I’m not sure if this is updating the Baz.F or just the instance that was currently assigned when I started working with it.

    The discrepancy is that readonly is viewed to do even more. It is viewed that readonly will make sure the assignment using Member should never be able to happen. This just isn’t the case and is only prevalent because of the lack of education. The same issues arise in other languages besides those on the .NET platform where immutability has to be enforced.

  4. Craig Eddy says:

    Justin: thanks for reassuring me. Just wanted to make sure I wasn’t missing something. 🙂

  5. Small side-note. I put up some considerations about this rule at:

    Hopefully between the comments I’ve left above and the contents of the entry we can get some good conversations going on the concepts of immutability and why it is so dern hard to do right now.

  6. Daniel O'Connell says:

    Wesner: I think it does sometimes, but much less often. A readonly field implies a referencevaluetype that cannot be changed, anywhere. The contents of it may but the reference itself never will. Combine that with the connotation of the term readonly(that the value can’t change) and you result in a logical suggestion of using immutable types in readonly fields in as many circumstances as possible. This allows you to make assumptions about a readonly field, such as returning a consistent hash code, a consistent type from GetType, a consistent string from ToString, etc.

    A get only property, on the other hand, only implies that the referencevaluetype cannot be changed *directly* by external code. It is still possible method calls allow the user to redefine the value of a property or that the internal state of the object may change that returned value, which would be the result of external, albeit indirect, action(infact, reading a get only property could change the value of the property).

    The concept and semantics of the two are very different, even if they disallow the same syntax.

  7. Max says:

    Another "classic" example for not using read only fields:

    class Foo()


    int m_Value;

    public int Value


    get{return m_Value;}set{m_Value=value;}


    public static readonly Foo Empty = new Foo (0);


    void Main()


    Foo f=Foo.Emtpy;


    //-> Foo.Empty is no longer "Empty"!


    This introduces some really nasty side effects if you arent aware of it so you better write a get only property for an "empty" Foo instance.

  8. RichB says:

    Some people don’t understand reference types. Period.

    I’ve worked on a 100,000 LOC (C#) project where the original author insisted on doing:

    X myvar=new X();

    FooBar(ref myvar);

    private void FooBar(ref X var) {




  9. Sean Malloy says:

    I’m not getting the difference between these two:

    class Counter


    public int Value;


    class Something


    private Counter c1;

    public readonly Counter CountField;

    public Something()


    c1 = new Counter();

    c1.Value = 1;

    CountField = new Counter();

    CountField.Value = 1;


    public Counter CountProperty


    get { return c1; }



    correct me if I’m wrong but:

    Something s = new Something();

    s.CountField.Value = 2;

    s.CountProperty.Value = 2;

    its effectively the same thing?

  10. Brad Abrams says:

    Sean — yes, you are right, those are the same thing… they both return a mutable reference and have the same problem

  11. Sean Malloy says:

    So, my question is:

    If they both have the same problem, why does FxCop pick up on one, and not on the other? Or does it? Have I missed the point here?

    I use mutable readonly fields as a subsitute for a get property all the time.

    The nice thing about C# as opposed to java, is that a public field can be refactored to a private field with a public get/set property accessor, and provided there is no reflection going on, code doesn’t need to be fixed anywhere else… Java is impossible to do that. You have to change all the calling code to use the get()/set() methods instead..

    Is this bad practice? I don’t use FxCop, so I haven’t seen what errors it would spit at me.

Skip to main content