Sdílet prostřednictvím


CA2227: Vlastnosti kolekce by měly být pouze pro čtení

Vlastnost Hodnota
ID pravidla CA2227
Název Vlastnosti kolekce by měly být pouze pro čtení
Kategorie Využití
Oprava způsobující chybu nebo chybu způsobující chybu Narušující
Povoleno ve výchozím nastavení v .NET 9 No

Příčina

Externě viditelná zapisovatelná vlastnost je typu, který implementuje System.Collections.ICollection. Toto pravidlo ignoruje pole, indexery (vlastnosti s názvem Item), neměnné kolekce, kolekce jen pro čtení a sady oprávnění.

Popis pravidla

Zapisovatelná vlastnost kolekce umožňuje uživateli nahradit kolekci úplně jinou kolekcí. Vlastnost jen pro čtení nebo init-only zastaví nahrazení kolekce, ale přesto umožňuje nastavit jednotlivé členy. Pokud je nahrazení kolekce cílem, upřednostňovaným vzorem návrhu je zahrnout metodu pro odebrání všech prvků z kolekce a metodu pro opětovné naplnění kolekce. Clear Příklad tohoto vzoru najdete v příkladu System.Collections.ArrayList třídy a AddRange metody.

Binární serializace i serializace XML podporují vlastnosti jen pro čtení, které jsou kolekce. Třída System.Xml.Serialization.XmlSerializer má specifické požadavky pro typy, které implementují ICollection a System.Collections.IEnumerable které mají být serializovatelné.

Jak opravit porušení

Chcete-li opravit porušení tohoto pravidla, nastavte vlastnost jen pro čtení nebo pouze inicializaci. Pokud to návrh vyžaduje, přidejte metody pro vymazání a opětovné naplnění kolekce.

Kdy potlačit upozornění

Upozornění můžete potlačit, pokud je vlastnost součástí třídy DTO (Data Transfer Object).

Jinak nepotlačujte upozornění z tohoto pravidla.

Potlačení upozornění

Pokud chcete pouze potlačit jedno porušení, přidejte do zdrojového souboru direktivy preprocesoru, abyste pravidlo zakázali a znovu povolili.

#pragma warning disable CA2227
// The code that's violating the rule is on this line.
#pragma warning restore CA2227

Pokud chcete pravidlo pro soubor, složku nebo projekt zakázat, nastavte jeho závažnost v none konfiguračním souboru.

[*.{cs,vb}]
dotnet_diagnostic.CA2227.severity = none

Další informace naleznete v tématu Jak potlačit upozornění analýzy kódu.

Příklad

Následující příklad ukazuje typ s zapisovatelnou kolekcí vlastnost a ukazuje, jak lze kolekci nahradit přímo. Kromě toho ukazuje upřednostňovaný způsob nahrazení vlastnosti kolekce jen pro čtení pomocí Clear a AddRange metody.

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

Viz také