Hay mucha desinformación sobre IDisposable. Es un PATRÓN que ayuda a lograr lo que solía realizarse tradicionalmente a través de un destructor en C++. El problema es que en .NET, la destrucción de un objeto no es determinista (no ocurre automáticamente cuando un objeto sale del alcance, sino que ocurre en el momento de la recolección de basura que está en un subproceso de baja prioridad separado).
No necesita implementar Eliminar a menos que tenga un recurso que deba ser liberado de alguna manera. Por ejemplo, si alguno de sus miembros de datos privados implementa Dispose, probablemente debería implementar Dispose también y llamar a Dispose sobre los miembros privados en su Dispose. Del mismo modo, debe liberar cualquier control PInvoke en Dispose.
Además, el método Dispose NO se llama automáticamente cuando se recolecta basura. Esta es la mayor desinformación. Debes llamar a Dispose desde tu Destructor (C#) o Finalize (VB.NET). Aquí es un buen patrón para la implementación de Desechar:
public class Foo : IDisposable
{
public Foo()
{
// Allocate some resource here
}
~Foo()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
}
private void Dispose(bool disposing)
{
// De-allocate resource here
if (disposing)
GC.SuppressFinalize(this);
}
}
La razón por la que llamar GC.SupressFinalize es que si el objeto tiene un finalizador, su objeto se consigue realmente promovido a la siguiente generación de GC, ya que tiene que llaman Finalice la primera vez que el GC corre alrededor, y no puede liberar su objeto hasta que finalice la finalización, y por lo tanto la memoria no se libera hasta el segundo recorrido por el GC. Si llama a Dispose manualmente, puede omitir el finalizador, permitiendo que su objeto se libere durante la primera pasada del GC.
Para obtener el mayor beneficio de botar, utilice el uso de keword:
using (Foo f = new Foo())
{
// Do something with Foo
}
Esto es exactamente lo mismo que si hubiera escrito esto:
Foo f;
try
{
f = new Foo();
// Do something with Foo
}
finally
{
f.Dispose();
}
Algunas personas, como para establecer una boolean en su clase llamado _disposed, y luego verifica ese bool durante cada llamada a un método, y lanza una excepción si intentas llamar a un método en un objeto después de invocar a Dispose. Para las clases de proyectos internos, generalmente considero esta exageración, pero podría ser una buena opción si está creando una biblioteca para el consumo de terceros.
También recomendaría encarecidamente un artículo titulado "IDisposable: Lo que su madre nunca le contó sobre la desasignación de recursos" en http://www.codeproject.com/KB/dotnet/IDisposable.aspx, aunque podría hacerte sentir que usar IDisposable de una manera absolutamente correcta es casi imposible. –