CA2227: Vlastnosti kolekce by měly být pouze pro čtení
TypeName |
CollectionPropertiesShouldBeReadOnly |
CheckId |
CA2227 |
Kategorie |
Microsoft.Usage |
Narušující změna |
Narušující |
Příčina
Externě viditelná zapisovatelná vlastnost je typ, který implementuje ICollection.Pole, indexéry (vlastnosti s názvem "Item") a sady oprávnění jsou tímto pravidlem ignorovány.
Popis pravidla
Zapisovatelná vlastnost kolekce umožňuje uživateli nahradit kolekci kompletně jinou kolekcí.Vlastnost jen pro čtení neumožňuje kolekci nahradit, ale stále umožňuje nastavit jednotlivé členy.Pokud je cílem nahrazení kolekce, tak upřednostňovaný návrhový vzor je zahrnutí metody pro odebrání všech prvků z kolekce a metoda opětovného naplnění kolekce.Jako příklad tohoto vzoru je vhodné se podívat na metody Clear a AddRange třídy ArrayList.
Obě binární i XML serializace podporují pouze vlastnosti pro čtení, které jsou kolekce.Třída XmlSerializer má zvláštní požadavky pro typy, které implementují ICollection a IEnumerable, aby byly serializovatelné.
Jak vyřešit porušení
Pro vyřešení porušení tohoto pravidla, vytvořte vlastnost jen pro čtení, a pokud to návrh vyžaduje, přidejte metody pro vyčištění a opětovného naplnění kolekce.
Kdy potlačit upozornění
Nepotlačujte upozornění na toto pravidlo.
Příklad
Následující příklad ukazuje typ se zapisovatelnou vlastností kolekce a ukazuje, jak lze kolekci přímo nahradit.Navíc, je zobrazen upřednostňovaný způsob nahrazení vlastnosti kolekce jen pro čtení pomocí metody Clear a 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);
}