1

I have a type which contains a collection of constant data. The constants are defined by a standard which is defined outside of my program. The type looks like this:

public class IAmImmutable
{
    public IAmImmutable(string member1, string member2)
    {
        this.Member1 = member1;
        this.Member2 = member2;
    }

    public string Member1 { get; private set; }

    public string Member2 { get; private set; }

    public static readonly Instance1 = new IAmImmutable("abc", "def");
    public static readonly Instance2 = new IAmImmutable("example", "data");
    public static readonly Instance3 = new IAmImmutable("for", "stackoverflow");
    public static readonly Instance4 = new IAmImmutable("these are", "constant fields");
    public static readonly Instance5 = new IAmImmutable("42", "1729");
    /* ... */
    public static readonly Instance1000 = new IAmImmutable("HUNGRY EVIL", "ZOMBIES");
}

This results in thousands of CA2104:DoNotDeclareReadOnlyMutableReferenceTypes detections from FxCop. The notes in this detection indicate that one should suppress the detection if the indicated type is immutable, which it is in this case. However, I don't want to have thousands and thousands of suppressions if I can avoid doing that.

Is it possible to mark this type as immutable and therefore prevent this detection from occuring?

Billy ONeal
  • 104,103
  • 58
  • 317
  • 552
  • http://blogs.msdn.com/b/codeanalysis/archive/2006/04/04/faq-how-do-i-indicate-to-donotdeclarereadonlymutablereferencetypes-that-a-type-is-immutable-david-kean.aspx – D Stanley Apr 16 '13 at 18:17
  • see http://stackoverflow.com/questions/2274412/immutable-readonly-reference-types-fxcop-violation-do-not-declare-read-only-m – Peter Ritchie Apr 16 '13 at 18:21
  • @Peter: That question is about an immutable type which contains internal mutable members. This type has no internal mutable members. If there was a `StringBuilder` inside that would be an entirely different question. – Billy ONeal Apr 16 '13 at 18:24

1 Answers1

2

See an article explaining how to do this on MSDN.

It appears that FxCop looks for a text file called ImmutableTypes.txt for types that it should consider "immutable".

For what it's worth, your class IS mutable from within, even though you don't explicitly mutate it. One change that would make it immutable is to change the properties from auto-implemented to get-only properties backed by readonly fields:

public IAmImmutable(string member1, string member2)
{
    this._Member1 = member1;
    this._Member2 = member2;
}

private readonly string _Member1;
private readonly string _Member2;

public string Member1 { get {return _Member1;} }
public string Member2 { get {return _Member2;} }

(Whether FxCop recognizes this as an "immutable" class is another question)

Note that this only works because string is immutable. If it were changed to a mutable type (like List or an Array), then the reference would be readonly but the contents could be modified, hence making the class itself mutable.

D Stanley
  • 149,601
  • 11
  • 178
  • 240
  • @D Stanley: Not really. Adding readonly only enforces anything at compile time for that class; if one was to add a mutating member to the class in the future they could just add that member and remove `readonly`. That would not be a breaking change. Of course, that could subtly break code expecting "free threading" but the framework would not complain. – Billy ONeal Apr 16 '13 at 18:29
  • The fact that a field is of a mutable reference type does not imply that the class is mutable, if there is no execution path via which the information encapsulated by the field could actually change. As a simple example, if the constructor of an object creates an array of five integers, fills in those values, and then stores a reference in a private field, and if it never exposes that array to anything that could mutate it, I would consider the class to be immutable (at least as far as the array is concerned). Further, knowing that the *identity* of the thing referred to by a field is... – supercat Apr 16 '13 at 18:41
  • ...constant is often useful even (*especially*) in cases where the content might change. Suppose, for example, a class uses an `int[]` to encapsulate some information and has a method that returns a `ReadOnlyCollection` that wraps it. If the `int[]` variable is readonly, then the wrapper will represent a live view of the collection; if code that wants to change a value always makes a copy, changes the copy, and makes the field point to the new copy, the wrapper will represent a snapshot. If the code uses the `int[]` the way list does, the wrapper may cease to be meaningful... – supercat Apr 16 '13 at 18:49
  • ...if the collection is changed. It's too bad neither .NET nor Java allows a declaration to specify whether a field encapsulates mutable state that might change, "mutable state" that won't be changed by code to which a reference is exposed, identity but not mutable state, identity and mutable state, or neither identity nor mutable state. Knowing what a field is supposed to encapsulate is very different from knowing its type. – supercat Apr 16 '13 at 18:53
  • @BillyONeal if you don't have an FxCop project file you can try putting it in the FxCop installation folder (likely `C:\Program Files\Microsoft Visual Studio {X}\Team Tools\Static Analysis Tools\FxCop\ImmutableTypes.txt`) – D Stanley Apr 16 '13 at 19:06
  • @D Stanley: That's not acceptable for this case unfortunately (I can't force the whole team to do that) – Billy ONeal Apr 16 '13 at 21:04