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.
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);
}
}
}