2011-04-07 17 views
13

Aunque hay un buen montón de Q & Como IDisposable con respecto a encontrar en SO, no he encontrado una respuesta a esto todavía:aplicación explícita de IDisposable

por lo general siguen la práctica que cuando uno de mi clases posee un objeto IDisposable y luego implementa IDisposable y llama al Dispose en el objeto propiedad. Sin embargo, recientemente me encontré con una clase que implementó IDisposable explícitamente, impidiéndome así llamar directamente al Dispose forzándome a lanzarlo, lo cual me pareció molesto e innecesario.

Así que la pregunta: ¿Por qué y cuándo uno querría utilizar una implementación de interfaz explícita de IDisposable? Sé que existen razones perfectamente válidas y válidas para implementar una interfaz explícitamente, pero con respecto a IDisposable, la razón no está del todo clara para mí.

+1

¿Cuáles son estas "buenas y válidas razones", y por qué no deberían contener también para "IDisposable"? ¿Y por qué es "molesto" lanzar un objeto a "IDisposable"? – chiccodoro

+2

A veces es necesario que una clase implemente dos o más interfaces cuyos nombres de miembros entrarían en conflicto. Es un buen y adecuado uso para nombrar interfaces explícitamente. Estoy de acuerdo con el OP en que la convención de nombrar arbitrariamente el método de limpieza como algo diferente a Dispose es tonto. Incluso si una clase tiene un método Close, eso no significa que no deba tener un método Dispose. Como llamar a Dispose después de llamar a Close es en el peor algo redundante, ¿qué hay de malo en tener ambos métodos? – supercat

+0

@chiccodoro: la implementación de la interfaz explícita IMO es útil sobre todo cuando se necesitan implementar dos interfaces que tienen miembros conflictivos. En cualquier otro caso, tener un objeto que se puede convertir en una interfaz en lugar de "ser", la interfaz no es natural y molesta. –

Respuesta

14

Yo diría que es inusual tener una implementación explícita de IDisposable.Dispose a menos que tenga un método equivalente alternativo (por ejemplo, Cerrar).

En cuyo caso su clase contenedora podría llamar Close en vez de casting.

Un ejemplo es la clase WebResponse en el Framework < = V3.5. Curiosamente, hay un método de eliminación pública en .NET 4, por lo que tal vez Microsoft haya decidido que una implementación explícita puede no ser una buena práctica.

Shawn Farkas, un ingeniero de diseño en el equipo de seguridad de CLR escribe en MSDN magazine que

Aunque el uso de bloques trabajará con las clases que tienen una aplicación IDisposable explícita, recomiendo que las clases no implementan la interfaz de este camino. Si implementa IDisposable explícitamente, los desarrolladores que están explorando el modelo de objetos utilizando IntelliSense® en Visual Studio no se dará cuenta de que el objeto tiene un método Dispose

+0

De hecho, la clase que quería envolver expuso un método 'Close 'que terminé usando. Es solo que el código de muestra proporcionado explícitamente contenía: 'using (SomeClass o = new SomeClass())' por lo que estaba claro que se recomendaba el uso del patrón desechable. – ChrisWue

1

Yo diría que es una buena práctica, obliga (a menos que desee echado a IDisposable !!) mediante el uso de

using (ClassWithIDisposable) { 
} 

Desechar se llamará incluso en el caso de una excepción

también al usar marcos COI como el castillo y la unidad al final tener a heredar a su IDisposable interfaz para que pueda ser llamado. Estos marcos permiten AOP por el cual no tiene una referencia a su clase sólida solo una interfaz ......

+0

Una instrucción using no es apropiada para el escenario descrito en la pregunta: una clase que posee un objeto IDisposable. – Joe

+0

Realmente no exige el uso de 'using'. Nadie puede impedirte hacer algo como esto 'var o = new MyDisposable(); o.DoSomething(); return; ' – ChrisWue

+0

¡Es cierto! Tampoco lo hace público ... Solo me refiero a llamar .Dispose() explícitamente –

1

En mi humilde opinión, hay una sola razón para que una clase implemente IDisposable explícitamente, que sería si es esperaba que nadie realmente tuviera que llamarlo. El hecho de que una clase implementa IDisposable explícitamente podría verse como un indicador de que uno puede crear con seguridad un objeto de esa clase particular, aunque no necesariamente un objeto de una clase derivada, y simplemente abandonarlo cuando se haya terminado con uno. La falta de un método Dispose directamente disponible en una clase en particular podría verse como un indicador de que llamar a Dispose sobre un objeto que se sabe que pertenece a esa clase particular no sería necesario.

Tenga en cuenta que tener y utilizar una referencia a un objeto que implementa IDisposable, sin darse cuenta de que lo hace, no es un problema; sin embargo, adquirir propiedad de tal objeto es. Un método de fábrica cuyo tipo de devolución no hace nada con IDisposable.Deséchelo e impleméntelo de manera explícita, pero que a veces devuelve un objeto que espera una eliminación adecuada, sería una receta para fugas. Una clase no debe implementar explícitamente IDisposable si se puede usar como el tipo de devolución de dicho método de fábrica.

Personalmente, mi inclinación sería eliminar todos los objetos que implementen IDisposable, lo necesiten o no. No obstante, saber que ciertos tipos particulares de objetos ID identificables pueden ser muy útiles en los casos en que garantizar una eliminación adecuada sería, de otro modo, difícil o incómodo.