Udostępnij za pośrednictwem


CA2227: Właściwości kolekcji powinny być tylko do odczytu

Właściwości Wartość
Identyfikator reguły CA2227
Tytuł Właściwości kolekcji powinny być tylko do odczytu
Kategoria Użycie
Poprawka powodująca niezgodność lub niezgodność Kluczowa
Domyślnie włączone na platformie .NET 9 Nie.

Przyczyna

Zewnętrznie widoczna, zapisywalna właściwość jest typu, który implementuje System.Collections.ICollection. Ta reguła ignoruje tablice, indeksatory (właściwości o nazwie "Item"), niezmienne kolekcje, kolekcje readonly i zestawy uprawnień.

Opis reguły

Właściwość kolekcji z możliwością zapisu umożliwia użytkownikowi zastąpienie kolekcji zupełnie inną kolekcją. Właściwość tylko do odczytu lub init-only uniemożliwia zastąpienie kolekcji, ale nadal umożliwia ustawienie poszczególnych elementów członkowskich. Jeśli zastąpienie kolekcji jest celem, preferowanym wzorcem projektu jest dołączenie metody w celu usunięcia wszystkich elementów z kolekcji oraz metody ponownego wypełniania kolekcji. Clear Zobacz metody System.Collections.ArrayList i AddRange klasy, aby zapoznać się z przykładem tego wzorca.

Zarówno serializacja binarna, jak i XML obsługują właściwości tylko do odczytu, które są kolekcjami. Klasa System.Xml.Serialization.XmlSerializer ma określone wymagania dotyczące typów implementujących ICollection i System.Collections.IEnumerable w celu serializacji.

Jak naprawić naruszenia

Aby naprawić naruszenie tej reguły, ustaw właściwość tylko do odczytu lub init-only. Jeśli projekt tego wymaga, dodaj metody w celu wyczyszczenia i ponownego wypełniania kolekcji.

Kiedy pomijać ostrzeżenia

Ostrzeżenie można pominąć, jeśli właściwość jest częścią klasy obiektu transferu danych (DTO ).

W przeciwnym razie nie pomijaj ostrzeżeń z tej reguły.

Pomijanie ostrzeżenia

Jeśli chcesz po prostu pominąć pojedyncze naruszenie, dodaj dyrektywy preprocesora do pliku źródłowego, aby wyłączyć, a następnie ponownie włączyć regułę.

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

Aby wyłączyć regułę dla pliku, folderu lub projektu, ustaw jego ważność na none w pliku konfiguracji.

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

Aby uzyskać więcej informacji, zobacz Jak pominąć ostrzeżenia dotyczące analizy kodu.

Przykład

W poniższym przykładzie pokazano typ z właściwością kolekcji z możliwością zapisu i pokazano, jak można bezpośrednio zamienić kolekcję. Ponadto pokazuje preferowany sposób zastępowania właściwości kolekcji tylko do odczytu przy użyciu metod Clear i AddRange .

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

Zobacz też