method - metodo dispose() c#
¿Cómo se puede saber si se dispone de una referencia de objeto IDisposable? (7)
Depende, hay objetos IDisposable
que permiten llamar al método Dispose
todo lo que desee, y hay objetos IDisposable
que arrojan ObjectDisposedException
. En tal caso, estos objetos deben rastrear el estado (por lo general implementado con un campo booleano privado está isDisposed
).
¿Hay algún método, o alguna otra forma ligera, para verificar si una referencia es a un objeto dispuesto?
PD: esto es solo una curiosidad (duerme bien, no en el código de producción). Sí, sé que puedo atrapar la ObjectDisposedException
al intentar acceder a un miembro del objeto.
El método Dispose
se requiere para realizar cualquier limpieza que se requiera antes de que se abandone un objeto; si no se requiere limpieza, no se requiere hacer nada. Requerir que un objeto haga un seguimiento de si ha sido eliminado, incluso cuando el método Dispose
no haría nada, requeriría muchos objetos IDisposable
para agregar un IDisposable
con un beneficio muy limitado.
Pudo haber sido útil si IDisposable
incluía dos propiedades: una que indicaba si un objeto necesitaba deshacerse , y una de las cuales indicaba que el objeto no había quedado inutilizado por eliminación. Para los objetos en los que la eliminación realmente hace algo, ambos valores serían inicialmente verdaderos y se volverían falsos después de Dispose
. Para los objetos donde la eliminación no necesita hacer ninguna limpieza, el primer método siempre puede devolver falso y el segundo siempre es cierto, sin tener que almacenar una bandera en cualquier lugar. Sin embargo, no creo que haya ninguna manera de agregarlas a .NET ahora.
Lo que me gusta hacer es declarar los objetos sin inicializarlos, pero establecer sus valores predeterminados en Nothing
. Luego, al final del ciclo, escribo:
If anObject IsNot Nothing Then anObject.Dispose()
Aquí hay una muestra completa:
Public Sub Example()
Dim inputPdf As PdfReader = Nothing, inputDoc As Document = Nothing, outputWriter As PdfWriter = Nothing
''code goes here that may or may not end up using all three objects,
'' such as when I see that there aren''t enough pages in the pdf once I open
'' the pdfreader and then abort by jumping to my cleanup routine using a goto ..
GoodExit:
If inputPdf IsNot Nothing Then inputPdf.Dispose()
If inputDoc IsNot Nothing Then inputDoc.Dispose()
If outputWriter IsNot Nothing Then outputWriter.Dispose()
End Sub
Esto también funciona muy bien para poner tus objetos principales en la parte superior de una rutina, usándolos dentro de una rutina de Try
, y luego tirarlos en un bloque Finally
:
Private Sub Test()
Dim aForm As System.Windows.Forms.Form = Nothing
Try
Dim sName As String = aForm.Name ''null ref should occur
Catch ex As Exception
''got null exception, no doubt
Finally
''proper disposal occurs, error or no error, initialized or not..
If aForm IsNot Nothing Then aForm.Dispose()
End Try
End Sub
No hay nada incorporado que permita esto. Debería exponer una propiedad booleana IsDisposed que refleje un indicador interno dispuesto.
public class SimpleCleanup : IDisposable
{
private bool disposed = false;
public bool IsDisposed
{
get
{
return disposed;
}
}
public SimpleCleanup()
{
this.handle = /*...*/;
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// free only managed resources here
}
// free unmanaged resources here
disposed = true;
}
}
public void Dispose()
{
Dispose(true);
}
}
No, la implementación predeterminada del patrón IDisposable no lo admite
Si no es su clase y no proporciona una propiedad IsDisposed (o algo similar, el nombre es solo una convención), entonces no tiene forma de saberlo.
Pero si es su clase y está siguiendo la implementación de IDisposable canónica , entonces simplemente exponga el campo _disposed o _isDisposed como una propiedad y verifique eso.
System.Windows.Forms.Control
tiene una propiedad IsDisposed
que se establece en true después de llamar a Dispose()
. En sus propios objetos identificables, puede crear fácilmente una propiedad similar.