CA2227: Propriedades de coleção devem ser somente leitura

Property Valor
ID da regra CA2227
Título Propriedades de coleção devem ser somente leitura
Categoria Usage
Correção interruptiva ou sem interrupção Quebra
Habilitado por padrão no .NET 8 Não

Causa

Uma propriedade externamente visível e gravável é de um tipo que implementa System.Collections.ICollection. Essa regra ignora matrizes, indexadores (propriedades com o nome 'Item'), coleções imutáveis, coleções somente leitura e conjuntos de permissões.

Descrição da regra

Uma propriedade de coleção gravável permite que um usuário substitua a coleção por uma coleção completamente diferente. Uma propriedade init-only ou somente leitura impede que a coleção seja substituída, mas ainda permite que os membros individuais sejam definidos. Se o objetivo for substituir a coleção, o padrão de design preferencial será incluir um método para remover todos os elementos da coleção e um método para preencher novamente a coleção. Consulte os método Clear e AddRange da classe System.Collections.ArrayList para obter um exemplo desse padrão.

Tanto a serialização binária quanto o XML dão suporte a propriedades somente leitura que são coleções. A classe System.Xml.Serialization.XmlSerializer possui requisitos específicos para tipos que implementam ICollection e System.Collections.IEnumerable para serem serializáveis.

Como corrigir violações

Para corrigir uma violação dessa regra, torne a propriedade somente leitura ou init-only. Se o design exigir, adicione os métodos para limpar e preencher novamente a coleção.

Quando suprimir avisos

É possível suprimir o aviso se a propriedade fizer parte de uma classe DTO (Objeto de Transferência de Dados).

Caso contrário, não suprima os avisos dessa regra.

Suprimir um aviso

Para suprimir apenas uma violação, adicione diretivas de pré-processador ao arquivo de origem a fim de desabilitar e, em seguida, reabilitar a regra.

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

Para desabilitar a regra em um arquivo, uma pasta ou um projeto, defina a severidade como none no arquivo de configuração.

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

Para obter mais informações, confira Como suprimir avisos de análise de código.

Exemplo

O exemplo a seguir mostra um tipo com uma propriedade de coleção gravável e como é possível substituir a coleção diretamente. Além disso, mostra a maneira preferencial de substituir uma propriedade de coleção somente leitura usando os métodos Clear e 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

Confira também