CA1049: Tipos com recursos nativos devem ser descartáveis

Item Valor
RuleId CA1049
Categoria Microsoft.Design
Alteração da falha Sem interrupção

Causa

Um tipo faz referência a um campo System.IntPtr, um campo System.UIntPtr ou um campo System.Runtime.InteropServices.HandleRef, mas não implementa System.IDisposable.

Descrição da regra

Essa regra pressupõe que os campos IntPtr, UIntPtr e HandleRef armazenem ponteiros para recursos não gerenciados. Tipos que alocam recursos não gerenciados devem implementar IDisposable para permitir que os chamadores liberem esses recursos sob demanda e reduzir o tempo de vida dos objetos que contêm os recursos.

O padrão de design recomendado para limpar recursos não gerenciados é fornecer um meio implícito e explícito para liberar esses recursos usando os métodos System.Object.Finalize e System.IDisposable.Dispose, respectivamente. O coletor de lixo chama o método Finalize de um objeto em algum momento indeterminado depois que o objeto é determinado como não mais acessível. Depois de Finalize ser chamado, uma coleta de lixo adicional é necessária para liberar o objeto. O método Dispose permite que o chamador libere explicitamente recursos sob demanda, antes que os recursos sejam liberados se deixados para o coletor de lixo. Depois de limpar os recursos não gerenciados, Dispose deve chamar o método System.GC.SuppressFinalize para informar ao coletor de lixo que Finalize não precisa mais ser chamado; isso elimina a necessidade da coleta de lixo adicional e reduz o tempo de vida do objeto.

Como corrigir violações

Para corrigir uma violação dessa regra, implemente IDisposable.

Quando suprimir avisos

É seguro suprimir um aviso dessa regra se o tipo não faz referência a um recurso não gerenciado. Caso contrário, não suprima um aviso dessa regra porque uma falha na implementação de IDisposable pode fazer com que os recursos não gerenciados fiquem indisponíveis ou subutilizados.

Exemplo

O exemplo a seguir mostra um tipo que implementa IDisposable para limpar um recurso não gerenciado.

using System;

namespace DesignLibrary
{
    public class UnmanagedResources : IDisposable
    {
        IntPtr unmanagedResource;
        bool disposed = false;

        public UnmanagedResources() 
        {
            // Allocate the unmanaged resource ...
        }

        public void Dispose() 
        {
            Dispose(true);
            GC.SuppressFinalize(this); 
        }

        protected virtual void Dispose(bool disposing)
        {
            if(!disposed)
            {
                if(disposing)
                {
                    // Release managed resources.
                }

                // Free the unmanaged resource ...

                unmanagedResource = IntPtr.Zero;

                disposed = true;
            }
        }

        ~UnmanagedResources()
        {
            Dispose(false);
        }
    }
}

CA2115: Chamar GC.KeepAlive ao usar recursos nativos

CA1816: Chamar GC.SuppressFinalize corretamente

CA2216: Tipos descartáveis devem declarar o finalizador

CA1001: Tipos com campos descartáveis devem ser descartáveis

Confira também