CA2227: Właściwości kolekcji powinny być tylko do odczytu
TypeName |
CollectionPropertiesShouldBeReadOnly |
CheckId |
CA2227 |
Kategoria |
Microsoft.Usage |
Zmiana kluczowa |
Kluczowa |
Przyczyna
Właściwość widoczna z zewnątrz, z możliwością zapisu, jest typem, który implementuje ICollection.Tablice, indeksatory (właściwości o nazwie "Item") i zestawy uprawnień są ignorowane przez regułę.
Opis reguły
Właściwość zapisywalnej kolekcji pozwala użytkownikowi zastąpić kolekcję zupełnie inną kolekcją.Właściwość tylko do odczytu uniemożliwia zastępowanie kolekcji, ale nadal umożliwia ustawienie poszczególnych członków.Jeśli celem jest zastąpienie kolekcji, preferowany wzorzec projektowania to dołączenie metody, usuwającej wszystkie elementy z kolekcji i metody do ponownego wypełnienia kolekcji.Zobacz metody Clear i AddRange z klasy ArrayList jako przykład tego wzorca.
Zarówno serializacja binarna i XML obsługują właściwość tylko do odczytu kolekcji.Klasa XmlSerializer ma szczególne wymagania dla typów, które implementują ICollection i IEnumerable w celu serializacji.
Jak naprawić naruszenia
Aby naprawić naruszenie tej zasady, należy ustawić właściwość tylko do odczytu i jeśli projekt tego wymaga, dodać metody, do wyczyszczenia i ponownego wypełnienia kolekcji.
Kiedy pominąć ostrzeżenia
Nie należy pomijać ostrzeżenia dotyczącego tej reguły.
Przykład
Poniższy przykład pokazuje typ z właściwością kolekcji możliwej do zapisu i pokazuje, jak można bezpośrednio zastąpić kolekcję.Ponadto pokazano preferowany sposób zastępowania kolekcji z właściwością tylko do odczytu za pomocą metod Clear i 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);
}