C# Language
Interfaz IDisponible
Buscar..
Observaciones
IDisposable
de los clientes de la clase que implementanIDisposable
asegurarse de que llamen al métodoDispose
cuando hayan terminado de usar el objeto. No hay nada en el CLR que busque directamente los objetos para invocar un métodoDispose
.No es necesario implementar un finalizador si su objeto solo contiene recursos administrados. Asegúrese de llamar a
Dispose
en todos los objetos que usa su clase cuando implemente su propio métodoDispose
.Se recomienda hacer que la clase sea segura contra múltiples llamadas a
Dispose
, aunque lo ideal sería que solo se llame una vez. Esto se puede lograr agregando una variableprivate bool
a su clase y estableciendo el valor entrue
cuando se haya ejecutado el métodoDispose
.
En una clase que contiene solo recursos gestionados
Los recursos administrados son recursos que el recolector de basura del tiempo de ejecución conoce y tiene bajo control. Hay muchas clases disponibles en el BCL, por ejemplo, como una SqlConnection
que es una clase de contenedor para un recurso no administrado. Estas clases ya implementan la interfaz IDisposable
: depende de su código limpiarlas cuando haya terminado.
No es necesario implementar un finalizador si su clase solo contiene recursos administrados.
public class ObjectWithManagedResourcesOnly : IDisposable
{
private SqlConnection sqlConnection = new SqlConnection();
public void Dispose()
{
sqlConnection.Dispose();
}
}
En una clase con recursos gestionados y no gestionados.
Es importante dejar que la finalización ignore los recursos administrados. El finalizador se ejecuta en otro subproceso: es posible que los objetos gestionados ya no existan en el momento en que se ejecuta el finalizador. La implementación de un método protegido de Dispose(bool)
es una práctica común para garantizar que los recursos administrados no tengan su método Dispose
llamado desde un finalizador.
public class ManagedAndUnmanagedObject : IDisposable
{
private SqlConnection sqlConnection = new SqlConnection();
private UnmanagedHandle unmanagedHandle = Win32.SomeUnmanagedResource();
private bool disposed;
public void Dispose()
{
Dispose(true); // client called dispose
GC.SuppressFinalize(this); // tell the GC to not execute the Finalizer
}
protected virtual void Dispose(bool disposeManaged)
{
if (!disposed)
{
if (disposeManaged)
{
if (sqlConnection != null)
{
sqlConnection.Dispose();
}
}
unmanagedHandle.Release();
disposed = true;
}
}
~ManagedAndUnmanagedObject()
{
Dispose(false);
}
}
IDisponible, Disponer
.NET Framework define una interfaz para los tipos que requieren un método de desmontaje:
public interface IDisposable
{
void Dispose();
}
Dispose()
se usa principalmente para limpiar recursos, como referencias no administradas. Sin embargo, también puede ser útil forzar la disposición de otros recursos incluso si se administran. En lugar de esperar a que el GC finalmente limpie también la conexión de su base de datos, puede asegurarse de que se haga en su propia implementación de Dispose()
.
public void Dispose()
{
if (null != this.CurrentDatabaseConnection)
{
this.CurrentDatabaseConnection.Dispose();
this.CurrentDatabaseConnection = null;
}
}
Cuando necesite acceder directamente a recursos no administrados, como punteros no administrados o recursos win32, cree una clase SafeHandle
de SafeHandle
y use las convenciones / herramientas de esa clase para hacerlo.
En una clase heredada con recursos gestionados
Es bastante común que pueda crear una clase que implemente IDisposable
, y luego derivar clases que también contengan recursos administrados. Se recomienda marcar el método de Dispose
con la palabra clave virtual
para que los clientes puedan limpiar los recursos que posean.
public class Parent : IDisposable
{
private ManagedResource parentManagedResource = new ManagedResource();
public virtual void Dispose()
{
if (parentManagedResource != null)
{
parentManagedResource.Dispose();
}
}
}
public class Child : Parent
{
private ManagedResource childManagedResource = new ManagedResource();
public override void Dispose()
{
if (childManagedResource != null)
{
childManagedResource.Dispose();
}
//clean up the parent's resources
base.Dispose();
}
}
usando palabras clave
Cuando un objeto implementa la interfaz IDisposable
, se puede crear dentro de la sintaxis de using
:
using (var foo = new Foo())
{
// do foo stuff
} // when it reaches here foo.Dispose() will get called
public class Foo : IDisposable
{
public void Dispose()
{
Console.WriteLine("dispose called");
}
}
using
azúcar sintáctica es para un bloque try/finally
; el uso anterior se traduciría aproximadamente en:
{
var foo = new Foo();
try
{
// do foo stuff
}
finally
{
if (foo != null)
((IDisposable)foo).Dispose();
}
}