Sdílet prostřednictvím


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);
}

Související pravidla

CA1819: Vlastnosti by neměly vracet pole