4

太久了,我让垃圾收集器发挥它的魔力,从我自己身上卸下所有责任。

可悲的是它从来没有变成一个问题......所以我从来没有考虑过这个问题。

现在,当我想到它时,我并不真正了解“处置”功能的真正作用以及应该如何以及何时实现它。

最后确定的相同问题...

最后一个问题...我有一个类图片操作:当我需要保存/调整大小/更改格式时...我启动该类的一个新实例,使用它的对象并且...让垃圾收集杀死该实例

class student
{
   public void displayStudentPic()
   {
      PictureManipulation pm = new PictureManipulation();
      this.studentPic = pm.loadStudentImage(id); 
   }
}

Class Test
{
  student a = new Student();
  a.displayStudentPic();
  // Now the function execution is ended... does the pm object is dead? Will the GC will kill it?
}
4

3 回答 3

4

关于你的class Student

我需要一个Dispose()吗?

假设 Picture 类是 IDisposable: Yes。因为 Student 对象“拥有” studentPicand 这使得它负责清理它。一个最小的实现:

class Student : IDisposable
{
   private PictureClass studentPic;
   public void Dispose()
   {
      if (studentPic != null)
        studentPic.Dispose();
   }
   ...
}

现在您使用 Student 对象,例如:

void Test
{
  using (Student a = new Student())
  {
     a.displayStudentPic();    
  } // auto Dispose by using() 
}

如果您不能/不使用using(){}块,只需a.Dispose();在完成后调用它。

但请注意,这里(远)更好的设计是避免在 Student 对象中保留图片对象。这引发了整个责任链。

我需要终结器吗?

没有。因为当一个 Student 对象被收集时,它的 studentPic 对象保证在同一次运行中被收集。终结器(析构函数)将毫无意义,但仍然很昂贵。

于 2010-08-18T14:28:59.420 回答
3

如果您的类型拥有一些非托管资源(如数据库连接、文件句柄等),或者您的类型拥有的某些对象实现了 IDisposable 接口,则只需要实现 Dispose 方法。在实现标准 Dispose 模式时,您应该考虑以下几点:

  • 如果您的对象不包含任何 IDisposable 对象或非托管资源(例如 DB 连接),那么您根本不需要实现 IDisposable 或终结器
  • 如果您的对象包含对 IDisposable 对象的引用,则在 Dispose 方法中对这些对象调用 Dispose()
  • 如果您的对象不包含任何非托管资源,则不要实现终结器,除非您已实现终结器,否则垃圾收集器将不会尝试终结您的对象(这会影响性能)。
  • 如果您的对象包含非托管资源,请在终结器中清理它们,而无需在 Dispose(bool) 方法中重新编写任何清理代码。
于 2010-08-18T09:27:29.120 回答
1

如果它拥有的资源不仅仅是对象本身所拥有的内存,那么您需要注意对象处置。

例如,如果你的对象抽象了一个文件,你必须控制文件何时被释放,否则你会搞砸非常糟糕的事情:你的应用程序使用完它仍然会被锁定,直到 GC 释放你的对象。

要了解如何正确执行此操作,请阅读有关 dispose 和 finalize 以及 using(){} 子句的手册。

于 2010-08-18T09:15:53.800 回答