Partilhar via


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 FTdescartável. Para cada campo F atribuído a um objeto criado localmente dentro dos métodos ou inicializadores do tipo Tque 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);
      }
   }
}

Consulte também