2009-07-20 18 views
7

Tengo un montón de objetos IDisposable en una tabla de búsqueda (simple diccionario antiguo <>, ahora mismo), pero para simplificar el código y evitar errores, estoy buscando una clase de colección que " posee "los artículos que tiene, y para evitar reinventar la rueda, ¿existe tal clase?Colección estándar para objetos IDisposable

La especificación debe ser que: - La colección debe ser desechable, y cuando se desecha, todos los artículos contenidos deben desecharse también. - Cuando se elimina un elemento, es Dispose() -d primero. - idealmente, la colección sería genérica con la restricción de tipo que impone el IDisposable -ness del tipo contenido.

sorta dudo existe una clase tal, pero me han sorprendido gratamente por la existencia de ReadOnlyCollection y ObservableCollection antes ...

Esencialmente, me gustaría que el equivalente de los contenedores STL C++, pero luego de el CLR ;-).

+0

Ha sido un poco de tiempo. ¿Hiciste una IDisposableCollection? Yo podría usarlo también – JohnV

+0

No; Terminé envolviendo la colección y exponiendo solo los (muy) pocos métodos que realmente necesitaba - agregar/obtener/eliminar - y alguna funcionalidad adicional para lo particular en que trabajé (muchos observadores del sistema de archivos). –

Respuesta

1

Está buscando CompositeDisposable.

using System.Reactive.Disposables; 

    ... 

    CompositeDisposable xs = new CompositeDisposable(Disposable.Empty); 
    xs.Add(Disposable.Empty); 
    xs.Add(Disposable.Empty); 
    xs.Dispose(); 
+0

No genérico.Eso no es del todo ideal; pero tampoco es un gran problema. –

+0

Las extensiones Rx no son parte de .NET Framework. Si bien no es un problema para muchos, no sería una buena idea hacer referencia a toda la biblioteca solo para una clase trivial. – arbiter

+0

@arbiter tiene un punto, aunque en mi humilde opinión no tiene mucho sentido no usar Rx. Una vez que haya tomado la decisión de aprovechar la enorme carga general de usar .net en un proyecto, nadie debería objetar acerca de traer bibliotecas útiles. –

0

Veo lo que pregunta, pero ¿qué tan difícil es hacer su propio método de eliminación que elimina el elemento antes de eliminarlo?

+0

No es difícil en absoluto, pero sería más limpio evitarlo si es posible. Y, no es solo Remove, right: cualquier método que pueda sobrescribir un elemento reemplaza implícitamente un elemento existente, que también debería ser Dispose() 'd. Si su colección implementa algunas interfaces estándar, puede haber bastantes variantes de estas funciones remove/setter, lo que lleva a la saturación del código. –

2

Por lo que sé, solo hay salidas tales colección para IComponents - Container implements IContainer. Para IDsposable genérico, creo que no tienes más opciones que "reinventar la rueda".

+0

Gracias, lo investigaré (aunque parece un poco pesado, la API tiene muchas cosas que no usaría, ¡eso podría no importar)! –

+0

Contenedor y System.ComponentModel parecen demasiado complejos e insuficientemente flexibles para uso general. En resumen, estoy aceptando su respuesta de que no tengo más opciones que "reinventar la rueda". –

1

Recuerde que su colección podría no ser la única que contiene los objetos desechables ... ¿Qué sucede si otro objeto (externo a la colección) hace referencia a uno de esos? Si se deshace de ella cuando la colección está dispuesta, ¿qué le pasaría al objeto?

Si estos objetos implementan IDisposable para la limpieza de algunos recursos no administrados, asegúrese de que implementen la finalización también y desechen los recursos no administrados allí.

+0

Actualmente controlo completamente tanto los objetos como la colección, por lo que esta es una situación hipotética. En todo caso; así es como funcionan las cosas con IDisposables, ¿verdad? Quiero decir, * alguien * tiene que poseer (es decir, eventualmente desecharlos), y en este caso el propietario es dueño de un número variable de identificables ID, por lo que una colección sería la más simple. –

0

¿Qué tal algo como esto:

public class DisposableEnumerable<T> : IEnumerable<T>, IDisposable where T : IDisposable 
{ 
    IEnumerable<T> Enumerable { get; } 

    public DisposableEnumerable(IEnumerable<T> enumerable) 
    { 
     Enumerable = enumerable; 
    } 

    public IEnumerator<T> GetEnumerator() 
    { 
     return Enumerable.GetEnumerator(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return Enumerable.GetEnumerator(); 
    } 

    public void Dispose() 
    { 
     foreach(var disposable in Enumerable) 
     { 
      disposable.Dispose(); 
     } 
    } 
} 
+0

Creo que un enumerable perezoso como argumento aquí es al menos engañoso; es importante saber que los objetos que pasas son realmente eliminados. Por supuesto, si la colección no se modifica, no importa. –

+0

También: a pesar de que no debería suceder, debe considerar lo que sucede si arroja un 'Dispose()' subyacente. –

+0

Buen punto, gracias. –

Cuestiones relacionadas