Share via


CA2227: Samlingsegenskaper ska vara skrivskyddade

Property Värde
Regel-ID CA2227
Rubrik Samlingsegenskaper ska vara skrivskyddade
Kategori Användning
Korrigeringen är icke-bakåtkompatibel Bryta
Aktiverad som standard i .NET 8 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

Se även