CA2213: Os campos descartáveis devem ser eliminados
Property | valor |
---|---|
ID da regra | CA2213 |
Título | Os campos descartáveis devem ser eliminados |
Categoria | Utilização |
A correção está quebrando ou não quebrando | Sem quebra |
Habilitado por padrão no .NET 9 | Não |
Motivo
Um tipo que implementa System.IDisposable declara campos que são de tipos que também implementam IDisposable. O Dispose método do campo não é chamado pelo Dispose método do tipo declarante.
Descrição da regra
Um tipo é responsável por descartar todos os seus recursos não gerenciados. A regra CA2213 verifica se um tipo descartável (ou seja, um que implementa IDisposable) T
declara um campo F
que é uma instância de um tipo FT
descartável. Para cada campo F
atribuído a um objeto criado localmente dentro dos métodos ou inicializadores do tipo T
que contém, a regra tenta localizar uma chamada para FT.Dispose
. A regra pesquisa os métodos chamados por T.Dispose
e um nível inferior (isto é, os métodos chamados pelos métodos chamados por T.Dispose
).
Nota
Além dos casos especiais, a regra CA2213 é acionada apenas para campos atribuídos a um objeto descartável criado localmente dentro dos métodos e inicializadores do tipo que contém. Se o objeto for criado ou atribuído fora do tipo T
, a regra não será acionada. Isso reduz o ruído para casos em que o tipo de contenção não é responsável pelo descarte do objeto.
Casos especiais
A regra CA2213 também pode ser acionada para campos dos seguintes tipos, mesmo que o objeto atribuído não seja criado localmente:
Passar um objeto de um desses tipos para um construtor e, em seguida, atribuí-lo a um campo indica uma transferência de propriedade de descarte para o tipo recém-construído. Ou seja, o tipo recém-construído passa a ser responsável pelo descarte do objeto. Se o objeto não for descartado, ocorrerá uma violação de CA2213.
Como corrigir violações
Para corrigir uma violação dessa regra, chame Dispose campos que são de tipos que implementam IDisposableo .
Quando suprimir avisos
É seguro suprimir um aviso desta regra se:
- O tipo sinalizado não é responsável por liberar o recurso mantido pelo campo (ou seja, o tipo não tem propriedade de eliminação)
- A chamada para Dispose ocorre em um nível de chamada mais profundo do que a regra verifica
- A propriedade de disposição do(s) campo(s) não é detida pelo tipo que contém.
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 CA2213
// The code that's violating the rule is on this line.
#pragma warning restore CA2213
Para desabilitar a regra de um arquivo, pasta ou projeto, defina sua gravidade como none
no arquivo de configuração.
[*.{cs,vb}]
dotnet_diagnostic.CA2213.severity = none
Para obter mais informações, consulte Como suprimir avisos de análise de código.
Configurar a análise de fluxo de dados
Use as seguintes opções para configurar a análise de fluxo de dados para esta regra:
- interprocedural_analysis_kind
- max_interprocedural_lambda_or_local_function_call_chain
- max_interprocedural_method_call_chain
- points_to_analysis_kind
- copy_analysis
- sufficient_IterationCount_for_weak_KDF_algorithm
Você pode configurar essas opções apenas para esta regra, para todas as regras às quais elas se aplicam ou para todas as regras nesta categoria (Security) às quais elas se aplicam. Para obter mais informações, consulte Opções de configuração da regra de qualidade de código.
Exemplo
O trecho a seguir mostra um tipo TypeA
que implementa IDisposableo .
public class TypeA : IDisposable
{
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// Dispose managed resources
}
// Free native resources
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// Disposable types implement a finalizer.
~TypeA()
{
Dispose(false);
}
}
O trecho a seguir mostra um tipo TypeB
que viola a regra CA2213 declarando um campo aFieldOfADisposableType
como um tipo descartável (TypeA
) e não chamando Dispose o campo.
public class TypeB : IDisposable
{
// Assume this type has some unmanaged resources.
TypeA aFieldOfADisposableType = new TypeA();
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
// Dispose of resources held by this instance.
// Violates rule: DisposableFieldsShouldBeDisposed.
// Should call aFieldOfADisposableType.Dispose();
disposed = true;
// Suppress finalization of this disposed instance.
if (disposing)
{
GC.SuppressFinalize(this);
}
}
}
public void Dispose()
{
if (!disposed)
{
// Dispose of resources held by this instance.
Dispose(true);
}
}
// Disposable types implement a finalizer.
~TypeB()
{
Dispose(false);
}
}
Para corrigir a violação, chame Dispose()
o campo descartável:
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
// Dispose of resources held by this instance.
aFieldOfADisposableType.Dispose();
disposed = true;
// Suppress finalization of this disposed instance.
if (disposing)
{
GC.SuppressFinalize(this);
}
}
}