views:

114

answers:

7

Hi,

My question is why do I need IDisposable? I have a class that consumes some resources that need to be freed. I have two options

Without IDisposable

class SomeUtilityClass
{
 public Stop()
 {
   // free resources
 }
}

With IDisposable

    class SomeUtilityClass, IDisposable
    {
     public void Dispose()
     {
       // free resources
     }
    }

So why do I need IDisposable here? It does not matther how to name the function.

class Program
{

 public Main(..)
 {
   SomeUtilityClass _class = new SomeUtilityClass();

   // clean up when we've done

  _class.Stop();

   // OR
  _class.Dispose();

 }
}
+5  A: 

Because IDisposable is supported by C# and you can use cool using syntax:

using (IDisposable someDisposable = new ...)
{
    // your code with someDisposable 
}

This is actually transformed by compiler to something like:

IDisposable someDisposable = new ...
IDisposable someDisposable2 = someDisposable ;
try
{
    // your code with someDisposable 
}
finally
{
    if (someDisposable2 != null)
    {
        someDisposable2.Dispose();
    }
}

So if any exception happens inside using block your object would be disposed anyway.

Andrew Bezzub
So the only reason to use IDisposable is 'just in case you're gonna use "using"'
Captain Comic
Main advantage of using is that it wraps your code with try/finally block so all your resources will be released correctly in case if exception occurres.
Andrew Bezzub
Right, so one can say IDisposable was introduced only to introduce "using" wrapping?
Captain Comic
Yes, and also to create common pattern used by all c# developers.
Andrew Bezzub
+1  A: 

IDisposable interacts with the using keyword to make it easy to clean up after yourself, e.g.:

using (var file = new FileStream(...))
{
    file.Write(...);
}

In the above code, the FileStream is closed as soon as the using block completes, rather than waiting around to be garbage-collected.

Marcelo Cantos
+1  A: 

It's a convention used in the C# language.

You also get the nifty using statement to your disposal.

using (SomeUtilityClass _class = new SomeUtilityClass()) {

} // Dispose is automatically called
Patrick
+1  A: 

As well as being able to use the using statement, it also give the garbage collector a hint that the object can be removed from memory.

Iain
Are you talking about public void Dispose()?
Captain Comic
your class implementing IDisposable will mark the assembly to be cleared by the GC, not just having the function
Iain
+1  A: 

Well in your case, there is not much point implementing IDisposable, since you can manually dispose of your resources.

A common use of IDisposable is when you expose an interface that handles data connections, and you want all derived classes to dispose when they're done.

Consider this:

public interface IDataCtx
{
   void CallDB();
}

public class MyDataCtx : IDataCtx
{ 
   private SqlConnection dc;

   public MyDataCtx() { dc = new SqlConnection(); dc.Open(); }

   public void CallDB();
   {
       dc.Something();
   }
}

Allowing you to do something like this:

IDataCtx ctx = new MyDataCtx();
ctx.CallDB();

But wait, what about that open connection? Uh oh!

If you made IDataCtx : IDisposable (and implemented the code in your derived ctx), you could do this:

IDataCtx ctx;
using (ctx = new MyDataCtx())
{
   ctx.CallDB();
}

Guaranteeing that whatever implementation of IDataCtx you use, it will always be disposed of (even in the case of an exception).

That's how i use it anyway. (plus it's just good practice).

RPM1984
Thanks for the sample code. But that REQUIRES me to use 'using', otherwise the gurantee is void?
Captain Comic
Correct. You could of course do try/catch/finally (and explicitly dispose in finally), but this is better practice.
RPM1984
+2  A: 

You should only really use IDisposable when your class consumes unmanaged resources, and they need to be freed immediately (streams, db etc).

It also provides a way for the CLR to 'clean up' when there are unhandled exceptions that cause your thread to be unloaded.

Calling IDisposable marks the object as being available for garbage collection immediately, but if not implemented correctly you can cause your object to be promoted a garbage collection generation which can cause memory pressure (refer to Jeffery Richters CLR via c# 3 if you want a full explanation).

a quick google turned this up: http://kleahy-technical.blogspot.com/2009/01/idisposable-and-garbage-collection.html

i suggest you read into the IDisposable pattern, when to use it, when not to and its implications on GC and state.

EDIT: there is loads of info on stackoverflow too: http://stackoverflow.com/questions/3148635/use-of-garbage-collection

CrapHands
+1  A: 

If your class owns unmanaged resources or your class owns managed IDisposable resources you should in generel implement the IDisposable interface.

An easy readable little article on when to implement IDisposable and Finalizers can be found here: http://nitoprograms.blogspot.com/2009/08/how-to-implement-idisposable-and.html

Fischer
That article omits a key usage case for iDisposabe: objects which subscribe to events from longer-lived objects. Any delegates you've added to a longer-lived object must be removed when your object ceases to be useful, or else the lifetime of your object--and anything else to which your object holds a reference--will be pegged to that of the longer-lived object.
supercat