Patrón Dispose en C#

En .NET, el patrón Dispose...

  1. DEBE implementarse si nuestra clase manejada mantiene referencias a recursos no manejados. Por ejemplo, clases C++/CLI que funcionan como wrappers de objetos C++ nativos, memoria nativa, etc.
  2. DEBE implementarse si nuestra clase debe liberar recursos limitados, incluso si son accedidos a través de objetos manejados. Por ejemplo, conexiones a Bases de Datos.
  3. DEBE implementarse si se quiere implementar RAII
  4. PUEDE, y DEBERÍA ser implementado si la clase contiene objetos manejados grandes (un Dictionary con muchas claves, por ejemplo), y sus instancias son creadas dinámicamente. En ese caso, implementar IDisposable nos permite usar la instrucción using de C# para acceder con semántica RAII. De esta forma, no sólo se libera la memoria lo antes posible, sino que si ocurre una excepción, la memoria es liberada en el acto.

Una vez que decidimos aplicar el patrón a una clase, hay dos posibilidades. En primer lugar, si la clase es sealed y no usa recursos no manejados, sólo hay que hacer un override del método Dispose:

public sealed class A : IDisposable{
    public void Dispose(){
        //Liberar recursos manejados y/o llamar a Dispose para los miembros
    }
}

Si la clase contiene recursos no manejados, o no es sealed, debemos aplicar la forma más general del patrón:

public class B : IDisposable{    
    public void Dispose(){
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing){
        if (disposing){
            // Liberar recursos manejados
        }   
        //Liberar recursos no manejados
    }

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

Comments

Popular posts from this blog

VB.NET: Raise base class events from a derived class

Apache Kafka - I - High level architecture and concepts

Upgrading Lodash from 3.x to 4.x