我是否需要在我的对象中实现处理或最终确定?

时间:2010-08-18 09:11:24

标签: c# dispose garbage-collection finalize

长久以来,我让垃圾收集器发挥其魔力,消除了我自己的所有责任。

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

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

完成同样的问题......

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

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?
}

3 个答案:

答案 0 :(得分:4)

关于class Student

  

我需要Dispose()吗?

假设Picture类是IDisposable:。因为Student对象'拥有'studentPic并且负责清理它。一个最小的实现:

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对象。 Finalizer(析构函数)毫无意义,但仍然很昂贵。

答案 1 :(得分:3)

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

  • 如果您的对象没有任何IDisposable对象或非托管资源(例如DB连接),那么您根本不需要实现IDisposable或终结器
  • 如果您的对象持有对IDisposable对象的引用,则在Dispose方法中对这些对象调用Dispose()
  • 如果您的对象没有任何非托管资源,那么不实现终结器,垃圾收集器将不会尝试最终确定您的对象(具有性能损失),除非您已实现终结器。
  • 如果您的对象拥有非托管资源,请在终结器中清除它们,而不必在Dispose(bool)方法中重写任何清理代码。

答案 2 :(得分:1)

如果对象处理只保留对象本身所拥有的内存以外的资源,则需要注意对象处理。

例如,如果你的对象抽象了一个文件,你必须在文件发布时处于控制状态,否则你会把事情弄得很糟糕:你的应用程序已经完成使用它仍然会被锁定,直到GC处理你的文件对象

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