1

I've gone through many article which says the purpose of IDisposable is to close the unmanaged objects like DB connections and Third party reports.But my question is why should I define Dispose method if I can handle the unmanaged objects in my methods without defining Dispose() method?

For an example,

class Report : IDisposable
{
    public void GenerateReport()
    {
        Report rpt=new Report() //unmanaged object created
        rpt.Dispose(); // Disposing the unmanaged object
    }

    private void Dispose()
    {
        //not sure why this block is needed
    }
}

Is my understanding correct?

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Jay
  • 41
  • 7
  • 2
    Hi Jay. You will probably find your questions (and many others!) answered at https://stackoverflow.com/questions/538060/proper-use-of-the-idisposable-interface. Also, don't be surprised if this question eventually gets marked as a duplicate - it has been covered before :-) – Adam Benson Jul 20 '20 at 10:29

4 Answers4

7

You're correct that you wouldn't need the implement IDisposable in your example. The example where you would is if you're keeping a long lived object for the life of the class you've written. So say you had this:

public class Report : IDisposable
{
  private Stream _reportStream; // This variable lives a long time.

  public void WriteToStream(byte[] data)
  {
    _reportStream.Write(data, 0, data.Length);
  }

  public void Dispose()
  {
    _reportStream?.Dispose();
  }
}

This is a fairly simple example, but it shows that _reportStream lives for the length of the class and needs to get cleaned up and garbage collected at the same time as the class. There's nothing stopping you from creating a public method called CleanupObject() to do the same thing, but then people can't use a using block to have the Runtime call the Dispose() automatically:

using (var myReport = new Report())
{
  // do a bunch of things with myReport;
} // Here the runtime will call myReport.Dispose() for you.

// myReport isn't accessible from here, as it was declared in the using block
Corith Malin
  • 1,505
  • 10
  • 18
1

The class that implements the IDisposable interface can be used in the using block. A big plus of this solution is that after leaving the block the Dispose method will be automatically called on the object created in this area. That way, we can only use classes that implement the IDisposable interface.

//example :
using(var dClean= new DisposableClean())
{
    //after leaving this using dClean will be automatically destroyed 
}

The object that you've created needs to expose some method, not necessary named Dispose(). You could also call it Clean(). Dispose() is the conventional name.

mike
  • 1,202
  • 1
  • 7
  • 20
1

Garbage Collector(GC), available throughout the .Net framwork, works well enough to be easily forgotten. However, it is worth learning to work with him well and use his possibilities. For this purpose, the correct implementation of the IDisposable interface is necessary, the basic form of which is sometimes insufficient if we consider the proper release of managed and unmanaged resources.

This is extanded version which can be very useful in this case. In a way an answer to you question:

public class DisposableExtended: IDisposable
{
   private bool isDisposed = false;

public void Dispose ()
{
   this.Dispose (true);
   GC.SupressFinalize (this);
}
protected void Dispose (bool disposing)
{
     if (! this.isDisposed)
     {
            if (disposing)
            {
             // here we release managed resources (standard classes)
            }
           // here we release unmanaged resources (e.g. streams, etc..)

     {
}

}
  this .isDisposed = true;
}

~ DisposableExtended ()
{
  this.Dispose (false);
}
JessicaOO
  • 88
  • 7
0

Yes, you can define your own way to release resources but many existing code use this way. If you share your code to people, remember to tell them to dispose in your way.

One "profit" of implementing IDisposable is that you can call Dispose indirectly by use a language construct such as using.

For example:

using(Stream s = File.OpenRead("HelloWorld.bin"))
            {
                //Do stuffs
            }