Notă
Accesul la această pagină necesită autorizare. Puteți încerca să vă conectați sau să modificați directoarele.
Accesul la această pagină necesită autorizare. Puteți încerca să modificați directoarele.
| Property | Value |
|---|---|
| Rule ID | CA2227 |
| Title | Collection properties should be read only |
| Category | Usage |
| Fix is breaking or non-breaking | Breaking |
| Enabled by default in .NET 10 | No |
| Applicable languages | C# and Visual Basic |
Cause
An externally visible, writable property is of a type that implements System.Collections.ICollection. This rule ignores arrays, indexers (properties with the name 'Item'), immutable collections, readonly collections, and permission sets.
Rule description
A writable collection property lets users replace the collection with a completely different collection. A read-only or init-only property prevents the collection from being replaced, but still allows individual members to be set. If replacing the collection is a goal, the preferred design pattern is to include a method to remove all elements from the collection, and a method to repopulate 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 to be serializable.
How to fix violations
Use one of the following approaches to fix a violation of this rule:
Make the property read-only or init-only. A read-only or init-only property prevents the collection from being replaced while still allowing individual members to be set. If the design requires replacing the collection's contents, add methods to clear and repopulate the collection. For an example of this pattern, see the ArrayList.Clear and ArrayList.AddRange methods.
Change the property type to a read-only collection type. If callers don't need to modify the collection, change the property type to a read-only collection, such as ReadOnlyCollection<T>. This approach makes the read-only intent explicit in the type signature.
Change the property type to a thread-safe concurrent collection type, while keeping the property read-only. If the design requires multiple threads to modify the collection concurrently, expose a read-only property (no setter) whose type is a concurrent collection, such as ConcurrentBag<T>. CA2227 is triggered by a writable collection property, not by the collection type, so the property must still be read-only. The concurrent collection choice only addresses thread-safe mutation of the returned collection instance.
When to suppress warnings
You can suppress the warning if the property is part of a Data Transfer Object (DTO) class.
Otherwise, don't suppress warnings from this rule.
Suppress a warning
If you just want to suppress a single violation, add preprocessor directives to your source file to disable and then re-enable the rule.
#pragma warning disable CA2227
// The code that's violating the rule is on this line.
#pragma warning restore CA2227
To disable the rule for a file, folder, or project, set its severity to none in the configuration file.
[*.{cs,vb}]
dotnet_diagnostic.CA2227.severity = none
For more information, see How to suppress code analysis warnings.
Example
The following example shows a type with a writable collection property and how you can replace the collection directly. It also shows the preferred way to replace a read-only collection property using Clear and AddRange methods.
public class WritableCollection
{
public ArrayList SomeStrings
{
get;
// This set accessor violates rule CA2227.
// To fix the code, remove this set accessor or change it to init.
set;
}
public WritableCollection()
{
SomeStrings = new ArrayList(new string[] { "one", "two", "three" });
}
}
class ReplaceWritableCollection
{
static void Main2227()
{
ArrayList newCollection = ["a", "new", "collection"];
WritableCollection collection = new()
{
// This line of code demonstrates how the entire collection
// can be replaced by a property that's not read only.
SomeStrings = newCollection
};
// If the intent is to replace an entire collection,
// implement and/or use the Clear() and AddRange() methods instead.
collection.SomeStrings.Clear();
collection.SomeStrings.AddRange(newCollection);
}
}
Public Class WritableCollection
' This property violates rule CA2227.
' To fix the code, add the ReadOnly modifier to the property:
' ReadOnly Property SomeStrings As ArrayList
Property SomeStrings As ArrayList
Sub New()
SomeStrings = New ArrayList(New String() {"one", "two", "three"})
End Sub
End Class
Class ViolatingVersusPreferred
Shared Sub Main2227()
Dim newCollection As New ArrayList(New String() {"a", "new", "collection"})
Dim collection As New WritableCollection()
' This line of code demonstrates how the entire collection
' can be replaced by a property that's not read only.
collection.SomeStrings = newCollection
' If the intent is to replace an entire collection,
' implement and/or use the Clear() and AddRange() methods instead.
collection.SomeStrings.Clear()
collection.SomeStrings.AddRange(newCollection)
End Sub
End Class