4

我有以下课程:

public class NewListBox : ListBox
    {
        public NewListBox()
        {
        }

        private ImageList _myImageList;

        public ImageList ImageList
        {
            get { return _myImageList; }
            set { _myImageList = value; }
        }
     }

我对处置此对象是否会触发处置对象上的字段(例如 ImageList)感兴趣,还是我应该实现(覆盖)Dispose 方法并自己完成这项工作?

4

4 回答 4

6

您应该将 ImageList 添加到控件的 Components 集合中,然后 Dispose 的基类实现将 Dispose 该集合中的所有内容,您不必自己重写 Dispose。

如果您有任何 IDisposable 但不是组件的成员,那么您将必须在您的控件中覆盖 Dispose 并自己处理它们。

(我在从 System.ComponentModel.Component 派生的对象的严格意义上使用术语组件)。

于 2012-05-17T11:11:01.530 回答
5

这篇文章很有帮助,在内存处理部分。

所有实现 IDisposable 的类(包括所有 Windows 窗体控件)都有一个 Dispose 方法。当不再需要对象以释放内存以外的资源时,必须调用此方法。发生这种情况有两种方式:

  • 手动(通过显式调用 Dispose)
  • 自动:通过将对象添加到 .NET 容器,例如 Form、Panel、TabPage 或 UserControl。容器将确保在处理它时,它的所有成员也是如此。当然,容器本身必须被处置(或者反过来,成为另一个容器的一部分)。对于 Windows 窗体控件,我们几乎总是将它们添加到容器中——因此依赖于自动处置。
于 2012-05-17T11:15:53.240 回答
1

这里有很多不同的答案..

我强烈建议阅读垃圾收集器基础知识和性能提示 如果你有两个选择:

  • 手动处理 ImageList,因此资源将很快释放(但不会立即释放)
  • 什么都不做:下次垃圾收集器分析你形成的世代时,资源将被释放。如果您的表单已关闭,并且没有任何内容保留对您的表单的引用,那么您的表单将被释放,然后由于不再有引用指向 ImageList,ImageList 将被释放。资源将被释放,但比第一种情况要晚一些。

除非您的 ImageList 中有数千张大图像(或者如果您创建/关闭表单数百次),您不会注意到这两种情况之间有任何区别

于 2012-05-17T11:52:11.063 回答
1

根据您发布的代码,您没有使用 Designer 来实现此控件。因此,您将没有设计器提供的Dispose(bool disposing)方法或System.CompononetModel.IContainer components可以添加额外控件的成员。我不确定 ListBox 如何处理其Controls属性,但如果它允许您在其中注册您的ImageList实例Controls.Add(ImageList),那应该会让您获得自动Dispose()行为。

您的另一个选择是覆盖Control.Dispose(bool)如下:

protected override void Dispose(bool disposing)
{
    // Only call Dispose() on members if invoked through a direct
    // call to `Dispose()`. (If disposing is false, that means
    // we are invoked through the finalizer and we should *only*
    // free up unmanaged resources that we *directly* own).
    if (disposing)
    {
        ImageList.Dispose();
    }

    base.Dispose(disposing);
}
于 2014-06-20T17:00:41.060 回答