Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
| Propriedade | Valor |
|---|---|
| ID da regra | CA2227 |
| Título | Propriedades de coleção devem ser somente leitura |
| Categoria | Usage |
| Correção interruptiva ou sem interrupção | Interrupção |
| Habilitado por padrão no .NET 10 | Não |
| Idiomas aplicáveis | C# e Visual Basic |
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 os usuários substituam a coleção por uma coleção completamente diferente. Uma propriedade somente leitura ou somente init impede que a coleção seja substituída, mas ainda permite que membros individuais sejam definidos. Se substituir a coleção for uma meta, o padrão de design preferencial será incluir um método para remover todos os elementos da coleção e um método para repovoar 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 tem requisitos específicos para tipos que implementam ICollection e System.Collections.IEnumerable para serem serializáveis.
Como corrigir violações
Use uma das seguintes abordagens para corrigir uma violação desta regra:
Torne a propriedade somente leitura ou apenas inicializável. Uma propriedade somente leitura ou somente init impede que a coleção seja substituída, ao mesmo tempo que permite que elementos individuais sejam definidos. Se o design exigir a substituição do conteúdo da coleção, adicione métodos para limpar e repovoar a coleção. Para obter um exemplo desse padrão, consulte os métodos ArrayList.Clear e ArrayList.AddRange.
Altere o tipo de propriedade para um tipo de coleção somente leitura. Se os chamadores não precisarem modificar a coleção, modifique o tipo da propriedade para uma coleção de leitura somente, como ReadOnlyCollection<T>. Essa abordagem torna a intenção de somente leitura explícita na assinatura do tipo.
Altere o tipo de propriedade para um tipo de coleção simultânea thread-safe, mantendo a propriedade somente leitura. Se o design exigir que vários threads modifiquem a coleção simultaneamente, exponha uma propriedade de leitura única (sem setter) cujo tipo é uma coleção simultânea, como ConcurrentBag<T>. CA2227 é disparado por uma propriedade de coleção gravável, não pelo tipo de coleção, portanto, a propriedade ainda deve ser somente leitura. A opção de coleção simultânea trata apenas da mutação thread-safe da instância de coleção retornada.
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 avisos desta 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 você pode substituir a coleção diretamente. Ele também mostra a forma preferida de alterar 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 = ["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