CA2227: Le proprietà di raccolte devono essere in sola lettura
TypeName |
CollectionPropertiesShouldBeReadOnly |
CheckId |
CA2227 |
Category |
Microsoft.Usage |
Breaking Change |
Breaking |
Causa
Una proprietà modificabile visibile a livello esterno è un tipo che implementa l'oggetto ICollection.Matrici, indicizzatori (proprietà con il nome 'Item') e set di autorizzazioni vengono ignorati dalla regola.
Descrizione della regola
Una proprietà di raccolta modificabile consente a un utente di sostituire la raccolta con una raccolta completamente differente.Una proprietà di sola lettura interrompe la sostituzione della raccolta ma consente ancora l'impostazione dei singoli membri.Se la sostituzione della raccolta è un obiettivo, il modello di progettazione preferito prevede l'inclusione di un metodo per rimuovere tutti gli elementi dalla raccolta e un metodo per reinserire i dati nella raccolta.Vedere i metodi Clear e AddRange della classe ArrayList per un esempio di questo modello.
La serializzazione XML e binaria supportano le proprietà di sola lettura che sono raccolte.La classe XmlSerializer presenta requisiti specifici per i tipi che implementano ICollection e IEnumerable in modo che siano serializzabili.
Come correggere le violazioni
Per correggere una violazione di questa regola, rendere la proprietà di sola lettura e, se la progettazione lo richiede, aggiungere metodi per cancellare e reinserire i dati nella raccolta.
Esclusione di avvisi
Non escludere un avviso da questa regola.
Esempio
Nell'esempio riportato di seguito viene visualizzata una proprietà di raccolta modificabile e viene illustrato il modo in cui è possibile sostituire direttamente la raccolta.Inoltre, viene visualizzata la maniera preferita di sostituire una proprietà di raccolta di sola lettura utilizzando i metodi Clear e AddRange.
Imports System
Imports System.Collections
Namespace UsageLibrary
Public Class WritableCollection
Dim strings As ArrayList
Property SomeStrings As ArrayList
Get
Return strings
End Get
' Violates the rule.
Set
strings = Value
End Set
End Property
Sub New()
strings = New ArrayList( _
New String() {"IEnumerable", "ICollection", "IList"} )
End Sub
End Class
Class ViolatingVersusPreferred
Shared Sub Main()
Dim newCollection As New ArrayList( _
New String() {"a", "new", "collection"} )
' strings is directly replaced with newCollection.
Dim collection As New WritableCollection()
collection.SomeStrings = newCollection
' newCollection is added to the cleared strings collection.
collection.SomeStrings.Clear()
collection.SomeStrings.AddRange(newCollection)
End Sub
End Class
End Namespace
using System;
using System.Collections;
namespace UsageLibrary
{
public class WritableCollection
{
ArrayList strings;
public ArrayList SomeStrings
{
get { return strings; }
// Violates the rule.
set { strings = value; }
}
public WritableCollection()
{
strings = new ArrayList(
new string[] {"IEnumerable", "ICollection", "IList"} );
}
}
class ReplaceWritableCollection
{
static void Main()
{
ArrayList newCollection = new ArrayList(
new string[] {"a", "new", "collection"} );
// strings is directly replaced with newCollection.
WritableCollection collection = new WritableCollection();
collection.SomeStrings = newCollection;
// newCollection is added to the cleared strings collection.
collection.SomeStrings.Clear();
collection.SomeStrings.AddRange(newCollection);
}
}
}
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);
}