Disposable Collection

Somebody asked me today, if we have a collection that is disposable and calls dispose on all its items when the collections.Dispose method is called. You can implement such collection by inheriting from List<T> and adding Dispose logic. If you add one additional requirement that Dispose is called on the items before they are removed from the collection when the collection is cleared, you need to use Collection<T> which can be customized more than List<T>. Here is a quick custom collection that does what I am talking about.

public class DisposableCollection<T> : Collection<T>, IDisposable where T: IDisposable {
   protected virtual void Dispose(bool disposing){
         foreach(T item in this){
   public void Dispose(){

   protected override void ClearItems(){

There are two problems with this collection though: a) what happens when an item is removed from the collection by calling Remove. b) what should the user do if they hold a reference to an item residing in the collection and then call Clear, which causes the item pointed to by the reference to be disposed:

var col  = DisposableCollection<Foo>();
col.Add(new Foo());
Foo f = col[0];
// now f points to a disposed object

… maybe Clear should not be disposing the items. What do you think?

Comments (12)

  1. Mark says:

    Additionally, what if one of the Items in Dispose throws?  When you use nested "using" statements to manage disposal, your objects will still (usually) be disposed if something throws because the dispose is in a finally block.  In the case of a disposing collection, any objects after the exception will not be disposed.  This is a big problem if you are handling exceptions and attempting to continue.  Those items will have to wait for garbage collection to be disposed, which may be problematic.  That’s something I’ve struggled with when creating a "disposing collection" like this.  A recursive "pop and dispose" algorithm would allow everything to at least get a chance to dispose.

  2. Mike says:

    I would say that a "Disposable" collection is more like a commodity, not a good programming practice. It’s difficult to choose how to implement things like Clear because we’re basically going back to problems that we had in C/C++, how’s responsability is to delete an object ? The container ? The client of the container ? If you take a look at STL or MFC collection classes none of them has a collection that does delete when you "clear" the collection.

  3. I think there should be a separate method called DisposeContents() in order to force the caller to have an explicit understanding of what is happening.

  4. Dick Dievendorff says:

    In the first case, the collection owns the disposable objects, and when you dispose the collection, other users of the collection items hold references to Disposed objects.  It’s no diffferent than

    Font font1 = new Font("Tahoma", 8);

    Font font2 = font1;


    // Gee, font2 isn’t of much use.

    As for remove, how about overriding the Remove method and Dispose the removed object?

  5. Garry Trinder says:

    Refcounting anyone ?

  6. Clear should never dispose the objects in the collection. This is because the objects may be resused somewhere or transferred to another collection, even if they are "owned" by the cleared collection.

    If you make Clear dispose objects you will cause a lot of grief for yourself if you use these collections in a visual studio designer.

    Here is how we do it in VG.net.

    A DisposeAll method can be used to dispose all children. The Clear method detaches children from their parent. A Remove method also detaches a child from a parent. Detached objects can be reused in other collections.

    If you Add an object to a collection, already contained by another colleciton, and it is an "owned" object, we remove it from the original collection, as we allow only one owner of such objects. In our system we enforice the one owner per object constraint consistently this way. If you need to put an identical object into another collection, you can use Clone, or a CopyTo or CopyFrom method.

  7. David Levine says:

    No refcounts, thank you vey much.

    One minor problem with the implementation defined above is that the Dispose method should also call GC.SuppresFinalize(this)

    Resource management in .NET is a very tricky subject.

    Other problems with the dispose pattern include:

    If there are classes from this base, and if the derived class overrides the Dispose(bool) method, then it should probably call the base class’s dispose method like this…

    proctected override void Dispose(bool disposing)


     try {

       // dispose logic here


     finally {




    Unfortunately, there’s no way to enforce this pattern on derived classes, and no way for the base class to detect and compensate for it.

    Another issue revolves around whether or not the base class should implement a Finalizer. If the objects need to be disposed then do they need to be disposed even if the caller does not call Dispose? Should there be a Finalizer, perhaps only in debug builds, to detect clients that do not invoke Dispose? If the collection requires that Dispose be invoked then its arguable that it should detect when a client is not using it correctly.

    There’s no single correct answer – the usage context determines the need for a Finalizer, but this issue needs to be thought about at design time.

    As to the original question: should Clear dispose of the item….my feeling is that it should not as it is not obvious that this is one of the side effects of invoking Clear(). Clear should simply clear the current contents of the list. An option is to provide an overload for Clear that contains a bool clear argument to provide explicit indication of the semantics of the call.

    IMO, Dispose should always dispose of the contained objects as one of the expectations of a DisposableCollection is that Disposing of the list itself should also dispose of all the objects that it contains.

  8. Also ref-counting is great, but in that case I don’t think we should use the word "owned" or "contained" — it becomes a collection of references, and generally those collections should be hidden from public.

  9. A disposable collection is a good idea. It’s pretty useful to have an System.ComponentModel.IContainer with components that fulfill some use case, and dispose all of them in a single shot by disposing the container. Externa references to the container items have never been a problem in my experience.

    Having similar funcionality in a more generic collection would be cool. (althouth I realize it’s trivial to implement ourselves… but that’s not the point ;))

  10. diegov says:

    I think the idea is that this collection *owns* its items and so manages their lifecycle (at least their life end). Maybe if you could find a name that made this more explicit (hmmm, ContainterCollection?), it could work. There is one additional issue: should a collection like this allow for item replacement like in col[n]=obj? I think no, unless it also calls dispose before sending the current col[n] in the bit bucket.

  11. Bill Sorensen says:

    You might want to check item vs. null before attempting to call item.Dispose().

  12. Bill Sorensen says:

    P.S.  I would disagree with Mr. Levine – there is no need to call SuppresFinalize, as the class does not implement a finalizer.