Question

In my VS2008 SP1, .NET 3.5 SP1 project, I have different classes that contain different properties. I use C#3.0 auto properties a lot.

Some of these properties need to be collections. Since I want to make it simple, I use ReadOnlyCollection<T> for these properties.

I don't want to use IEnumerable<T> since I want random access to the elements.

I use Code Analysis (FxCop rules) and I get the CA2227 warning.

I don't understand why does ReadOnlyCollection<T> should have a set method while it can't be changed... The set method can only do exactly what the property can do.

Example:

using System.Collections.ObjectModel;

namespace CA2227
{
    public class MyClass
    {
        public ReadOnlyCollection<int> SomeNumbers { get; set; }
    }
}

CA2227 : Microsoft.Usage : Change 'MyClass.SomeNumbers' to be read-only by removing the property setter. C:\Users...\Visual Studio 2008\Projects\CA2227\MyClass.cs 7 CA2227

Was it helpful?

Solution

A ReadOnlyCollection cannot be changed, but there's no reason why a property with a setter that is of type ReadOnlyCollection can't be changed to refer to a different ReadOnlyCollection. If you want the SomeNumbers property to be immutable, then it needs to be both of a read-only type, and also have a non-public setter.

EDIT

If you're convinced in what you want, then although FxCop is correct to warn you, you are happy with the warning. If you want to get rid of it, then include a SuppressMessage attribute at that point - as long as you also define a CODE_ANALYSIS constant in the project properties before you build, FxCop will honour that attribute and just not issue that particular warning on that particular occasion.

OTHER TIPS

It's rather odd to block changes to the contents of the collection without also blocking changes to the collection itself. If you want to be able to set the collection from within your class while conserving the use of automatic properties, you could use a private setter. e.g.:

public ReadOnlyCollection<int> SomeNumbers { get; private set; }

Consider using

public class MyClass
{
    public IReadOnlyList<int> SomeNumbers { get; set; }
}

ReadOnlyCollection = http://msdn.microsoft.com/en-us/library/ms132474(v=vs.110).aspx

IReadOnlyList = http://msdn.microsoft.com/en-us/library/hh192385(v=vs.110).aspx

The problem with ReadOnlyCollection, is that it still inherits from ICollection, and still has .Add, even though documentation say it will throw - http://msdn.microsoft.com/en-us/library/cc672239(v=vs.110).aspx

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top