Question

For too long I let the garbage collector do its magic, removing all responsibilities from my self.

Sadly it never turned into an issue... So I never gave a second thought to the subject.

Now when I think about it I don't really understand what the "dispose" function really does and how and when it should be implemented.

The same question for finalize...

And a last question... I have a class pictureManipulation : when I need to save/resize/change format ... I start a new instance of that class use its objects and... well let the garbage collection kill the instance

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?
}
Was it helpful?

Solution

Regarding your class Student

Do I need a Dispose() ?

Assuming the Picture class is IDisposable: Yes. Because a Student object 'owns' the studentPic and that makes it responsible for cleaning it up. A minimal implementation:

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

And you now use a Student object like:

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

If you can't/don't use a using(){} block, simply call a.Dispose(); when you're done with it.

But please note that the (far) better design here would be to avoid keeping a picture object inside your Student object. That sets off a whole chain of responsibilities.

Do I need a Finalizer?

No. Because when a Student object is being collected, its studentPic object is guaranteed to be collected in the same run. A Finalizer (destructor) would be pointless but still expensive.

OTHER TIPS

You only need to implement the Dispose method if your type holds some unmanaged resources like DB connections, file handles, etc. or if some of the objects that are held by your type implement the IDisposable interface. Here is a few points you should consider when implementing the standard Dispose pattern:

  • if your object doesn’t hold any IDisposable objects or unmanaged resources (DB connection, for example) then you don’t need to implement the IDisposable or finalizer at all
  • if your object holds references to IDisposable objects, then call Dispose() on these objects in the Dispose method
  • if your object doesn’t hold any unmanaged resources then don’t implement a finalizer, the Garbage Collector won’t attempt to finalize your object (which has a performance hit) unless you have implemented a finalizer.
  • if your object holds unmanaged resources, clean them up in the finalizer without re-writing any of the cleanup code in the Dispose(bool) method already.

You need to take care about object disposal if it holds resources other than just memory held by the object itself.

For instance, if your object abstracts a file, you must be in control when the file is released, or, you will mess things up very bad: your app finished using it and it will still be locked, until GC disposes your object.

To know how to do it properly, read manuals about dispose and finalize as well as the using(){} clause.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top