CA1049: Los tipos que poseen recursos nativos deben ser descartables
Nombre de tipo |
TypesThatOwnNativeResourcesShouldBeDisposable |
Identificador de comprobación |
CA1049 |
Categoría |
Microsoft.Design |
Cambio problemático |
Poco problemático |
Causa
Un tipo hace referencia a un campo System.IntPtr, un campo System.UIntPtr o un campo System.Runtime.InteropServices.HandleRef, pero no implementa System.IDisposable.
Descripción de la regla
Esta regla supone que IntPtr, UIntPtr y el almacén de campos HandleRef apunta a los recursos no administrados. Los tipos que se asignan a recursos no administrados deberían implementar IDisposable para permitir que los llamadores liberen estos recursos a petición y reduzcan el período de duración de los objetos que contienen los recursos.
El modelo de diseño recomendado para limpiar los recursos no administrados es proporcionar un modo implícito y otro explícito para liberar esos recursos mediante el método Object.Finalize y el método IDisposable.Dispose respectivamente. El recolector de elementos no utilizados llama al método Finalize de un objeto en algún momento indeterminado después de que el objeto se establezca como no alcanzable. Después de llamar a Finalize, es necesario que la recolección de elementos no utilizados libere el objeto. El método Dispose permite que el llamador libere explícitamente recursos a petición, antes de que los recursos sean liberados si acaban en el recolector de elementos no utilizados. Después que limpia los recursos no administrados, Dispose debe llamar al método GC.SuppressFinalize para permitir que la recolección de elementos no utilizados sepa que ya no es necesario llamar a Finalize; esto evita que sea necesaria la recolección de elementos no utilizados y reduce el período de duración del objeto.
Cómo corregir infracciones
Para corregir una infracción de esta regla, implemente IDisposable.
Cuándo suprimir advertencias
Es seguro suprimir una advertencia de esta regla si el tipo no hace referencia a un recurso no administrado. En caso contrario, no suprima ninguna advertencia de esta regla, porque si no se implementa IDisposable puede hacer que los recursos no administrados queden no disponibles o infrautilizados.
Ejemplo
El ejemplo siguiente muestra un tipo que implementa IDisposable para limpiar un recurso no administrado.
Imports System
Namespace DesignLibrary
Public Class UnmanagedResources
Implements IDisposable
Dim unmanagedResource As IntPtr
Dim disposed As Boolean = False
Sub New
' Allocate the unmanaged resource ...
End Sub
Overloads Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
Protected Overloads Overridable Sub Dispose(disposing As Boolean)
If Not(disposed) Then
If(disposing) Then
' Release managed resources.
End If
' Free the unmanaged resource ...
unmanagedResource = IntPtr.Zero
disposed = True
End If
End Sub
Protected Overrides Sub Finalize()
Dispose(False)
End Sub
End Class
End Namespace
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);
}
}
}
Reglas relacionadas
CA2115: Llamar a GC.KeepAlive cuando se utilicen recursos nativos
CA1816: Llamar a GC.SuppressFinalize correctamente
CA2216: Los tipos descartables deben declarar el finalizador
CA1001: Los tipos que poseen campos descartables deben ser descartables
Vea también
Referencia
Implementar Finalize y Dispose para limpiar recursos no administrados