CA2227: Collection properties should be read only
TypeName | CollectionPropertiesShouldBeReadOnly |
CheckId | CA2227 |
Category | Microsoft.Usage |
Breaking Change | Breaking |
An externally visible writable property is a type that implements System.Collections::ICollection. Arrays, indexers (properties with the name 'Item'), and permission sets are ignored by the rule.
A writable collection property allows a user to replace the collection with a completely different collection. A read-only property stops the collection from being replaced but still allows the individual members to be set. If replacing the collection is a goal, the preferred design pattern is to include a method to remove all the elements from the collection and a method to re-populate the collection. See the Clear and AddRange methods of the System.Collections::ArrayList class for an example of this pattern.
Both binary and XML serialization support read-only properties that are collections. The System.Xml.Serialization::XmlSerializer class has specific requirements for types that implement ICollection and System.Collections::IEnumerable in order to be serializable.
The following example shows a type with a writable collection property and shows how the collection can be replaced directly. Additionally, the preferred manner of replacing a read-only collection property using Clear and AddRange methods is shown.
using namespace System; using namespace System::Collections; namespace UsageLibrary { public ref class WritableCollection { public: // Violates the rule. property ArrayList^ SomeStrings; WritableCollection() { SomeStrings = gcnew ArrayList( gcnew array<String^> {"IEnumerable", "ICollection", "IList"} ); } }; } using namespace UsageLibrary; void main() { ArrayList^ newCollection = gcnew ArrayList( gcnew array<String^> {"a", "new", "collection"} ); // strings is directly replaced with newCollection. WritableCollection^ collection = gcnew WritableCollection(); collection->SomeStrings = newCollection; // newCollection is added to the cleared strings collection. collection->SomeStrings->Clear(); collection->SomeStrings->AddRange(newCollection); }