Partilhar via


CA2227: As propriedades da coleção devem ser somente leitura

Propriedade valor
ID da regra CA2227
Cargo As propriedades da coleção devem ser somente leitura
Categoria Utilização
A correção está quebrando ou não quebrando Quebrando
Habilitado por padrão no .NET 8 Não

Causa

Uma propriedade gravável visível externamente é de um tipo que implementa System.Collections.ICollection. Esta 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 somente leitura ou somente inicialização impede que a coleção seja substituída, mas ainda permite que os membros individuais sejam definidos. Se a substituição da coleção for uma meta, o padrão de design preferido 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 Clear métodos e AddRange da System.Collections.ArrayList classe para obter um exemplo desse padrão.

A serialização binária e XML oferece suporte a propriedades somente leitura que são coleções. A System.Xml.Serialization.XmlSerializer classe tem 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 métodos para limpar e preencher novamente a coleção.

Quando suprimir avisos

Você pode suprimir o aviso se a propriedade fizer parte de uma classe DTO (Data Transfer Object).

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

Suprimir um aviso

Se você quiser apenas suprimir uma única violação, adicione diretivas de pré-processador ao seu arquivo de origem para desativar e, em seguida, reativar 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 de um arquivo, pasta ou projeto, defina sua gravidade como none no arquivo de configuração.

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

Para obter mais informações, consulte 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 mostra como a coleção pode ser substituída diretamente. Além disso, ele mostra a maneira preferida de substituir uma propriedade de coleção somente leitura usando Clear e AddRange métodos.

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

Consulte também