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