If a generic collection is instantiated to contain iDisposable items, do the items get disposed?

こ雲淡風輕ζ 提交于 2019-12-10 16:13:12

问题


For example:

Queue<System.Drawing.SolidBrush> brushQ = new Queue<System.Drawing.SolidBrush>();
...
brushQ.Clear();

If I don't explicitly dequeue each item and dispose of them individually, do the remaining items get disposed when calling Clear()? How about when the queue is garbage collected?

Assuming the answer is "no", then what is the best practice? Do you have to always iterate through the queue and dispose each item?

That can get ugly, especially if you have to try..finally around each dispose, in case one throws an exception.

Edit

So, it seems like the burden is on the user of a generic collection to know that, if the items are Disposable (meaning they are likely to be using unmanaged resources that won't be cleaned up by the garbage collector), then:

  1. When you remove an item from the collection, make sure you Dispose() it.
  2. DON'T CALL Clear(). Iterate through the collection and dispose of each item.

Maybe the documentation for the generic collections should mention that.


回答1:


When do you expect them to be disposed? How will the collection know if there are other references to the objects in it?




回答2:


The generic collections don't actually know anything about the type of object they contain, so calling Clear will not cause them to call Dispose() on the items. The GC will eventually dispose of them once the collection itself gets disposed of, provided nothing else has an active reference to one of those items.

If you want to ensure that the objects have their Dispose method called when you call Clear on the collection you would need to derive your own collection and override the appropriate methods and make the calls yourself.




回答3:


Let me see if I can write an example code for this one.

Edit:

The following code implements an IDisposable Queue:

class DisposableQueue<T>:Queue<T>,IDisposable where T:IDisposable

    #region IDisposable Members

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    public virtual void Dispose(bool disposing) {
        if (disposing) {
            foreach (T type in this) {
                try
                {
                    type.Dispose();
                }
                finally {/* In case of ObjectDisposedException*/}
            }
        }
    }
    #endregion
}



回答4:


As others have said, it won't happen. However, you could build your own extension method to dispose them if you want.



来源:https://stackoverflow.com/questions/496722/if-a-generic-collection-is-instantiated-to-contain-idisposable-items-do-the-ite

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!