Partilhar via


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

Propriedade valor
ID da regra CA2227
Título As propriedades da coleção devem ser somente leitura
Categoria Utilização
A correção causa interrupção ou não Interrupção
Habilitado por padrão no .NET 10 Não
Línguas aplicáveis C# e Visual Basic

Motivo

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 aos utilizadores substituir a coleção por uma coleção completamente diferente. Uma propriedade de apenas leitura ou apenas init-only impede que a coleção seja substituída, mas ainda permite definir membros individuais. Se substituir a coleção for um objetivo, o padrão de design preferido é incluir um método para remover todos os elementos da coleção e um método para repovoar a coleção. Consulte os Clear métodos e AddRange da System.Collections.ArrayList classe para obter um exemplo desse padrão.

Tanto a serialização binária quanto a XML oferecem suporte a propriedades somente de leitura que são colecções. A System.Xml.Serialization.XmlSerializer classe tem requisitos específicos para que os tipos que implementam ICollection e System.Collections.IEnumerable sejam serializáveis.

Como corrigir violações

Use uma das seguintes abordagens para corrigir uma violação desta regra:

  • Torne a propriedade apenas de leitura ou apenas de inicialização. Uma propriedade de apenas leitura ou init apenas impede que a coleção seja substituída, permitindo que membros individuais sejam definidos. Se o design exigir substituir o conteúdo da coleção, adicione métodos para limpar e repovoar a coleção. Para um exemplo deste padrão, veja os ArrayList.Clear métodos e ArrayList.AddRange .

  • Altere o tipo de propriedade para um tipo de coleção de somente leitura. Se quem liga não precisar de modificar a coleção, altere o tipo de propriedade para uma coleção de apenas leitura, como ReadOnlyCollection<T>. Esta abordagem torna explícita a intenção de apenas leitura na assinatura do tipo.

  • Altere o tipo de propriedade para um tipo de coleção concorrente segura para threads, mantendo a propriedade apenas de leitura. Se o design exigir múltiplas threads para modificar a coleção em simultâneo, exponha uma propriedade somente de leitura (sem método setter) cujo tipo é uma coleção concorrente, como ConcurrentBag<T>. O CA2227 é acionado por uma propriedade de coleção mutável, não pelo tipo de coleção em si, pelo que a propriedade deve continuar a ser somente leitura. A escolha de coleção concorrente apenas aborda a mutação thread-safe da instância de recolha devolvida.

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 os 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 seguinte mostra um tipo com uma propriedade de coleção que pode ser escrita e como pode substituir a coleção diretamente. Também mostra a forma preferida de substituir uma propriedade de coleção apenas de 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 = ["a", "new", "collection"];

        WritableCollection collection = new()
        {
            // This line of code demonstrates how the entire collection
            // can be replaced by a property that's not read only.
            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