CA2227: Samlingsegenskaper ska vara skrivskyddade
Property | Värde |
---|---|
Regel-ID | CA2227 |
Title | Samlingsegenskaper ska vara skrivskyddade |
Kategori | Användning |
Korrigeringen är icke-bakåtkompatibel | Brott |
Aktiverad som standard i .NET 9 | Nej |
Orsak
En externt synlig, skrivbar egenskap är av en typ som implementerar System.Collections.ICollection. Den här regeln ignorerar matriser, indexerare (egenskaper med namnet Objekt), oföränderliga samlingar, skrivskyddade samlingar och behörighetsuppsättningar.
Regelbeskrivning
Med en skrivbar samlingsegenskap kan en användare ersätta samlingen med en helt annan samling. En skrivskyddad eller init-only-egenskap hindrar samlingen från att ersättas, men tillåter fortfarande att enskilda medlemmar anges. Om det är ett mål att ersätta samlingen är det önskade designmönstret att inkludera en metod för att ta bort alla element från samlingen och en metod för att fylla i samlingen igen. Clear Se klassens metoder System.Collections.ArrayList och AddRange för ett exempel på det här mönstret.
Både binär och XML-serialisering stöder skrivskyddade egenskaper som är samlingar. Klassen System.Xml.Serialization.XmlSerializer har specifika krav för typer som implementerar ICollection och System.Collections.IEnumerable för att kunna serialiseras.
Så här åtgärdar du överträdelser
Åtgärda ett brott mot den här regeln genom att göra egenskapen skrivskyddad eller init-only. Om designen kräver det lägger du till metoder för att rensa och fylla i samlingen igen.
När du ska ignorera varningar
Du kan ignorera varningen om egenskapen ingår i en DTO-klass (Data Transfer Object).
Annars ska du inte ignorera varningar från den här regeln.
Ignorera en varning
Om du bara vill förhindra en enda överträdelse lägger du till förprocessordirektiv i källfilen för att inaktivera och aktiverar sedan regeln igen.
#pragma warning disable CA2227
// The code that's violating the rule is on this line.
#pragma warning restore CA2227
Om du vill inaktivera regeln för en fil, mapp eller ett projekt anger du dess allvarlighetsgrad till none
i konfigurationsfilen.
[*.{cs,vb}]
dotnet_diagnostic.CA2227.severity = none
Mer information finns i Så här utelämnar du kodanalysvarningar.
Exempel
I följande exempel visas en typ med en skrivbar samlingsegenskap och visar hur samlingen kan ersättas direkt. Dessutom visas det bästa sättet att ersätta en skrivskyddad samlingsegenskap med hjälp av Clear
och AddRange
metoder.
public class WritableCollection
{
public ArrayList SomeStrings
{
get;
// This set accessor violates rule CA2227.
// To fix the code, remove this set accessor or change it to init.
set;
}
public WritableCollection()
{
SomeStrings = new ArrayList(new string[] { "one", "two", "three" });
}
}
class ReplaceWritableCollection
{
static void Main2227()
{
ArrayList newCollection = new ArrayList(new string[] { "a", "new", "collection" });
WritableCollection collection = new WritableCollection();
// This line of code demonstrates how the entire collection
// can be replaced by a property that's not read only.
collection.SomeStrings = newCollection;
// If the intent is to replace an entire collection,
// implement and/or use the Clear() and AddRange() methods instead.
collection.SomeStrings.Clear();
collection.SomeStrings.AddRange(newCollection);
}
}
Public Class WritableCollection
' This property violates rule CA2227.
' To fix the code, add the ReadOnly modifier to the property:
' ReadOnly Property SomeStrings As ArrayList
Property SomeStrings As ArrayList
Sub New()
SomeStrings = New ArrayList(New String() {"one", "two", "three"})
End Sub
End Class
Class ViolatingVersusPreferred
Shared Sub Main2227()
Dim newCollection As New ArrayList(New String() {"a", "new", "collection"})
Dim collection As New WritableCollection()
' This line of code demonstrates how the entire collection
' can be replaced by a property that's not read only.
collection.SomeStrings = newCollection
' If the intent is to replace an entire collection,
' implement and/or use the Clear() and AddRange() methods instead.
collection.SomeStrings.Clear()
collection.SomeStrings.AddRange(newCollection)
End Sub
End Class