Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
| Egenskap | Värde |
|---|---|
| Regel-ID | CA2227 |
| Title | Samlingsegenskaper ska vara skrivskyddade |
| Kategori | Användning |
| Korrigeringen är antingen invasiv eller icke-invasiv | Avbrott |
| Aktiverad som standard i .NET 10 | Nej |
| Tillämpliga språk | C# och Visual Basic |
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 användarna ersätta samlingen med en helt annan samling. En skrivskyddad eller init-only-egenskap förhindrar att samlingen ersätts, 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 AddRange och System.Collections.ArrayList för ett exempel på det här mönstret.
Både binär och XML-serialisering stöder egenskaper för endast läsning som är samlingar. Klassen System.Xml.Serialization.XmlSerializer har specifika krav att typer som implementerar ICollection och System.Collections.IEnumerable måste kunna serialiseras.
Så här åtgärdar du överträdelser
Använd någon av följande metoder för att åtgärda ett brott mot den här regeln:
Gör egenskapen skrivskyddad eller init-only. En skrivskyddad eller init-only-egenskap förhindrar att samlingens objekt ersätts samtidigt som individuella medlemmar kan anges. Om designen kräver att samlingens innehåll ersätts lägger du till metoder för att rensa och fylla i samlingen igen. Ett exempel på det här mönstret finns i ArrayList.Clear metoderna och ArrayList.AddRange .
Ändra egenskapstypen till en skrivskyddad samlingstyp. Om anropare inte behöver ändra samlingen ändrar du egenskapstypen till en skrivskyddad samling, till exempel ReadOnlyCollection<T>. Det här tillvägagångssättet gör den skrivskyddade avsikten explicit i typsignaturen.
Ändra egenskapstypen till en trådsäker samtidig samlingstyp, samtidigt som egenskapen hålls skrivskyddad. Om designen kräver flera trådar för att ändra samlingen samtidigt exponerar du en skrivskyddad egenskap (ingen setter) vars typ är en samtidig samling, till exempel ConcurrentBag<T>. CA2227 utlöses av en skrivbar egenskap för samlingar, inte av samlingstypen, så egenskapen måste fortfarande vara endast läsbar. Valet av samtidig samling adresserar endast trådsäker mutation av den returnerade samlingsinstansen.
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 hur du kan ersätta samlingen direkt. Den visar också 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 = ["a", "new", "collection"];
WritableCollection collection = new()
{
// This line of code demonstrates how the entire collection
// can be replaced by a property that's not read only.
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