2010-07-31 13 views
8

Realmente estoy buscando sabiduría sobre las mejores prácticas. Así que aquí están las preguntas, agregaré más si la gente deja comentarios. Siéntase libre de responder algunas o todas estas preguntas.¿Cuándo debería usar IDisposable? ¿Alguna vez se equivoca al usarlo? ¿Qué hay de tirar el encadenamiento?

¿Cuándo DEBO usar IDisposable? ¿Solo cuando tengo recursos no administrados?

¿Qué variaciones del patrón de disposición existen y por qué varían?

¿Cuáles son los recursos comunes no administrados que debo tener en cuenta?

¿Alguna vez fue erróneo o engañoso implementar IDisposable?

¿Debería deshacerse de las llamadas alguna vez encadenadas juntas, o deberíamos confiar en el uso de las declaraciones? Por ejemplo:

public Dispose(bool disposing) 
{ 
    ... 
    this.SomeDependency.Dispose; 
} 

Respuesta

6

Wow. ¡Muchas preguntas aquí!

¿Cuándo DEBO usar IDisposable? ¿Solo cuando tengo recursos no administrados?

IDisposablees generalmente utilizado para limpiar los recursos, pero eso no es necesariamente todo lo que es bueno para. Es un patrón general notificar al objeto consumido que ha terminado con él. Un ejemplo es un contador de tiempo:

using(var timer = new MyTimer()) 
{ 
    //do some stuff 
} 

En este caso, llamar Dispose no es necesariamente la liberación de los recursos, que es sólo una convenientes & consistentes forma de saber el temporizador "OK, yo (dos claves para un modelo!) 'He terminado con usted ahora' y el temporizador puede detener el cronometraje, y tal vez registrar el tiempo en alguna parte.

Otra buena regla general es si necesita tener un finalizador, por la razón que sea, generalmente también debe proporcionar IDisposable acceso a la misma rutina para que la clase pueda optar por finalizar la clase antes en lugar de esperar en el GC .

¿Qué variaciones del patrón disponer hay y por qué varían?

Sólo hay un tipo real "específico" de aplicación IDisposable yo sepa - Finalizar el/patrón Desechar:

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

    protected virtual void Dispose(bool disposing) 
    { 
     if (disposing) 
     { 
     // Free other state (managed objects). 
     } 
     // Free your own state (unmanaged objects). 
     // Set large fields to null. 
    } 

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

¿Cuáles son los recursos no administrados comunes que debería tener en cuenta?

Se debe suponer que todo lo que implemente IDisposable, especialmente en las bibliotecas .NET, tiene identificadores a recursos no administrados y debe desecharse. Normalmente, solo accederá a recursos no administrados a través de estos. Si no, lo sabrá, generalmente construyendo un controlador o algo.

¿Es erróneo o erróneo implementar IDisposable?

Puede ser inútil abusar de él, pero no es directamente dañino.

debe deshacerse llamadas nunca se encadenen

Una clase sólo debe desechar cualquier IDisposables que crea internamente. Si tiene dependencias desechables que se inyectaron o viven más allá del alcance de la clase, nunca debe deshacerse de ellas.

+1

¡Grandes respuestas! Bien pensado señor! – Firoso

3

Hay dos cosas principales que he escrito con respecto IDisposable, y le recomiendo que lea al menos la primera de ellas: How to Implement IDisposable and Finalizers - 3 Easy Rules (también tengo other blog posts on the subject) y IDisposable - What Your Mother Never Told You about Resource Deallocation.

¿Cuándo DEBO usar IDisposable? ¿Solo cuando tengo recursos no administrados?

IDisposable se debe utilizar para una de tres cosas: liberar un recurso no administrado, liberar recursos administrados y RAII. Prefiero usar diferentes patrones para estas diferentes necesidades.

Tenga en cuenta que el resto de mis respuestas (y los enlaces) están discutiendo IDisposable en el contexto de la liberación de recursos. No abordan RAII.

¿Qué variaciones del patrón de disposición existen y por qué varían?

El patrón de Microsoft es el más conocido. Maneja la liberación de recursos no administrados y administrados y permite la herencia. Prefiero un patrón más simple descrito en mi blog (3 easy rules), que es el patrón que Microsoft tiene actualmente seguido desde .NET 2.0.

¿Cuáles son los recursos comunes no administrados de los que debería tener conocimiento?

Mi preferencia es tener una sola clase IDisposable para cada tipo de recurso no administrado (similar al SafeFileHandle de Microsoft). Entonces, cada vez que agrega un tipo de recurso no administrado a su programa/biblioteca, solo debe manejarlo una vez.

La pregunta entonces es "¿qué clases debo eliminar?", Que tiene una respuesta simple: "todas las clases que implementan IDisposable".

¿Alguna vez fue erróneo o engañoso implementar IDisposable?

No. Una implementación vacía IDisposable es siempre una opción. Usted debería considerar agregar IDisposable a interfaces o clases base si cree que una implementación puede usarlas. Este es un problema de diseño, que analizo más en mi artículo What Your Mother Never Told You.

¿Debería deshacerse de las llamadas que alguna vez se encadenaron juntas, o deberíamos confiar en el uso de las declaraciones?

Es común que Dispose llame al Dispose en todos los objetos miembros que posee. Ver mi publicación de blog second rule para más detalles.

+0

dv inexplicable ?? –

Cuestiones relacionadas