MSDN's example pattern para implementar un método Dispose() representa el establecimiento de la referencia a un recurso gestionado dispuesto en null (_resource = null
), sino que lo hace fuera de la if (disposing)
bloque:MSDN Dispose() ejemplo erróneo? (Cuando para establecer referencias que gestiona a NULL)
protected virtual void Dispose(bool disposing)
{
// If you need thread safety, use a lock around these
// operations, as well as in your methods that use the resource.
if (!_disposed)
{
if (disposing) {
if (_resource != null)
_resource.Dispose();
Console.WriteLine("Object disposed.");
}
// Indicate that the instance has been disposed.
_resource = null;
_disposed = true;
}
}
no deben 't _resource = null
se coloca dentro de este bloque de código? Si se realiza una llamada al Dispose(false)
, entonces _resource
será nulo y no podrá eliminarse posteriormente. ??
Por supuesto, Dispose(false)
solo es llamado (en la práctica) por el tiempo de ejecución durante la finalización. Pero si no se eliminó previamente _resource
, ¿cuál es la necesidad de establecerlo como nulo en este punto cuando el objeto (incluido el campo de miembro _resource
) está a punto de ser recolectado como basura?
[fin de la pregunta original]
Seguimiento:
Después de mucho leer, parece asignar la referencia a nulo no es necesario, pero puede ser una buena idea para el miembro de "pesado" objetos si tiene motivos para creer que la clase contenedora (la que se está eliminando) podría no ser recogida pronto.
Sepa que la eliminación de objetos no es garantía de que el objeto ha sido "liberado" por el código de consumo. El objeto eliminado puede mantenerse alrededor (en una colección o de otro modo) para diversos fines, o simplemente por error. Puedo imaginarme una aplicación que usa objetos de una colección y luego los descarta, pero los mantiene en la colección para un proceso posterior para realizar la eliminación y registrar el estado final (o algo así ... quién sabe ...)
Conclusiones:
- Configuración de referencias a objetos miembro "pesados" a nULL los libera para la recolección de basura, incluso si el objeto desechado no se libera.
- Es excesivo borrar referencias para todos los objetos.
- Por lo tanto, la colocación de la declaración
_resource = null
(la pregunta original) no es importante por dos motivos: (A) Usarlo en absoluto es solo algo en lo que pensar después de leer lo anterior; (B) En el ejemplo de MSDN, se ejecuta paraDispose(true)
yDispose(false)
, pero este último solo se produce cuando el objeto está finalizado y está a punto de ser recogido de todos modos.
Por lo tanto, mi preferencia será para colocar en el interior del _resource = null
if
bloque más interno:
if (disposing) {
if (_resource != null) {
_resource.Dispose();
_resource = null;
}
}
Esto mantiene todo el código _resource
juntos. Pensamientos adicionales, ¿alguien?
Más lectura:
- In the Dispose(bool) method implementation, Shouldn't one set members to null?
- Do you need to dispose of objects and set them to null?
- http://www.codeproject.com/KB/dotnet/idisposable.aspx (muy bueno, y mucho!)
Se sirve de poco, pero poco daño ... En realidad, sería más molesto por una: la escritura a 'Console', y B: escribir a' Console' incluso si ya se dispone y nos webs 't disponerlo (ver llaves faltantes en el' si '). –
¡Jaja! La 'Console.Writeline()' es código de muestra. Trace.Writeline() te haría mejor? Además, no faltan llaves, está al final de la línea 'if' (no es compatible con StyleCop). –
mira de nuevo; Escribe "Objeto dispuesto". incluso si '_resource' era nulo y, por lo tanto, no llamaba a' .Dispose() '. Me refiero a * inner-most * 'if'. –