如果通用集合被实例化以包含iDisposable项目,那么这些项目是否会被处置?

时间:2009-01-30 18:55:02

标签: c# .net idisposable

例如:

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

如果我没有明确地将每个项目出列并单独处理它们,那么在调用Clear()时是否会处理剩余的项目?队列被垃圾收集时怎么样?

假设答案是“不”,那么最佳做法是什么?您是否必须始终遍历队列并处理每个项目?

这可能会变得很难看,特别是如果你必须尝试..最终围绕每个处置,以防万一抛出异常。

修改

因此,对于通用集合的用户而言,如果项目是Disposable(意味着他们可能正在使用不会被垃圾收集器清理的非托管资源),那么似乎负担很重要。然后:

  1. 从集合中删除项目时,请确保Dispose()它。
  2. 不要打电话给Clear()。迭代通过 收集和处理每个 项目
  3. 也许通用集合的文档应该提到它。

4 个答案:

答案 0 :(得分:5)

泛型集合实际上并不知道它们包含的对象类型,因此调用Clear不会导致它们对项目调用Dispose()。一旦集合本身被处理掉,GC将最终处置它们,前提是没有其他任何东西可以有效地引用其中一个项目。

如果要确保在对集合调用Clear时调用对象的Dispose方法,则需要派生自己的集合并覆盖相应的方法并自行调用。

答案 1 :(得分:4)

您希望什么时候处理它们?该集合将如何知道其中是否有其他对象的引用?

答案 2 :(得分:2)

让我看看我是否可以为此编写一个示例代码。

编辑:

以下代码实现了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
}

答案 3 :(得分:0)

正如其他人所说,它不会发生。但是,如果需要,您可以构建自己的扩展方法来处置它们。