Auflistungseigenschaften sollten schreibgeschützt sein

Aktualisiert: November 2007

     TypeName

CollectionPropertiesShouldBeReadOnly

CheckId

CA2227

Kategorie

Microsoft.Usage

Unterbrechende Änderung

Breaking

Ursache

Eine extern sichtbare schreibbare Eigenschaft ist ein Typ, der System.Collections.ICollection implementiert. Arrays, Indexer (Eigenschaften mit dem Namen 'Item') und Berechtigungssätze werden von der Regel ignoriert.

Regelbeschreibung

Eine schreibbare Auflistungseigenschaft ermöglicht einem Benutzer, die Auflistung durch eine vollkommen andere Auflistung zu ersetzen. Eine schreibgeschützte Eigenschaft sorgt dafür, dass die Auflistung nicht mehr ersetzt wird, lässt aber dennoch das Festlegen einzelner Member zu. Wenn das Ziel darin besteht, die Auflistung zu ersetzen, sollte in das Entwurfsmuster eine Methode eingefügt werden, die alle Elemente aus der Auflistung entfernt, sowie eine Methode, mit der die Auflistung neu aufgefüllt wird. Ein Beispiel für dieses Muster finden Sie in der Clear-Methode und der AddRange-Methode der System.Collections.ArrayList-Klasse.

Sowohl die binäre als auch die XML-Serialisierung unterstützen schreibgeschützte Eigenschaften, bei denen es sich um Auflistungen handelt. Für die System.Xml.Serialization.XmlSerializer-Klasse bestehen bestimmte Anforderungen für Typen, die ICollection und System.Collections.IEnumerable implementieren, um serialisierbar zu sein.

Behandlung von Verstößen

Um einen Verstoß gegen diese Regel zu beheben, definieren Sie die Eigenschaft als schreibgeschützt, und – falls erforderlich für das Design – fügen Sie Methoden zum Leeren und erneuten Auffüllen der Auflistung hinzu.

Wann sollten Warnungen unterdrückt werden?

Unterdrücken Sie keine Warnung dieser Regel.

Beispiel

Das folgende Beispiel zeigt einen Typ mit einer schreibbaren Auflistungseigenschaft und verdeutlicht, wie die Auflistung direkt ersetzt werden kann. Zudem wird die bevorzugte Methode des Ersetzens einer schreibgeschützten Auflistungseigenschaft mit der Clear-Methode und der AddRange-Methode veranschaulicht.

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

Verwandte Regeln

Eigenschaften sollten keine Arrays zurückgeben