views:

120

answers:

4

After going through a lot of articles of Idisposable i got confused about it usage. All articles explain what is it and how to implement. I want to understand what we will miss if we don't have it. It is an interface with one method Dispose() in it. Let's take an example Often the use of dispose is shown as disposing a database connection.

The code would be like

Public class Test:Idisposable
{
  public Test()
  {
     DatabaseConnection databaseConnection = new DatabaseConnection();
  }

  public void Dispose()
  {
     if (this.databaseConnection != null)
     {
      this.databaseConnection.Dispose();
      this.databaseConnection = null;
     }
  }
}

Although dispose is implemented but inside dispose method the dispose property of databaseconnection is used to free the connection(this.databaseConnection.Dispose();)

My question is why do we need to implement IDisposable in this case? We can directly call this.databaseConnection.Dispose() and free the connection. Why to implement dispose when internally also it calls the dispose property of the object. Alternative to the approach of Idisposable we can implement a method Release to free the memory.

Public Class Test
{

public Test()
{
  DatabaseConnection databaseConnection = new DatabaseConnection();
}
public void Release()
{
   if (this.databaseConnection != null)
   {
      this.databaseConnection.Dispose();
      this.databaseConnection = null;
   }

}
}

What is the difference in the two approaches? Do we really need Idisposable? I am looking forward for a concrete explanation.

+8  A: 

You are right, using your Release method you would get the exact same effect, provided you always remember to call it.

The reason why you should use Dispose / IDisposable for this sort of thing is consistency. All .NET developers will know about the IDisposable pattern, and a class being IDisposable indicates that you should dispose of it, and do it using the Dispose method. In other words, using the IDisposable pattern immediately tells another developer, that he should release the resources held by the class, and he should do it by calling the Dispose method.

Another benefit of implementing IDisposable is the using block, which works on any IDisposable class:

using(var t = new Test())
{
    // use t
}

Using the above code will result in t being Dispose()ed at the end of the using block. It is syntactic sugar for a try...finally block, but it tends to make this kind of code more concise and easier to read and write.

driis
@driis apart from consistency do you see any other motivating factor to use Idisposable
Piyush
@Piyush - Not allowing the client programmer to use a keyword in the language is rather a big deal that goes well beyond consistency.
Hans Passant
+1  A: 
  1. If your Release() worked correctly (it doesn't, but that's a different matter), then people would have to learn about it, and learn something else with another class, and so on.
  2. Your Release() could never be found programatically. It's possible to programatically call Dispose() when applicable with:

    if(obj is IDisposable) ((IDisposable)obj).Dispose();

While not often done, when it is done, it's vital.

It is sometimes useful to have a method like your Release() if its possible someone might want to call it during object use. An example of this is Close() on Stream. Note here though that Stream.Dispose() still exists, and calls into Close().

Jon Hanna
+1  A: 

IDisposable is worth implementing, mostly, because it's idomatic in C#. Everybody knows what IDisposable does, and how to deal with an object that implements IDisposable. When you are releasing resources using something other than IDisposable.Dispose(), you're deviating from the generally-understood idiom.

This means that a maintainer doesn't have to know the ins and outs of your particular class to prevent leaking resources. This may even be you, in 6 months, when you've forgotten most of what you've done with this piece of code! All you need to know is that it implements IDisposable, which has a commonly-understood meaning.

Remember that IDisposable, mostly, is a signal to a developer, "Hey, I'm a class that holds references to unmanaged resources. You probably shouldn't wait on the garbage collector to clean me up." Note that this may be indirectly via composition (a class that implements IDisposable because it has private members that implement IDisposable). When a decent C# developer sees a class implementing IDisposable, they should immediately think "This object is special, and needs to be cleaned up when I'm done with it." There's nothing preventing you from writing a Release() method; it just means that you're more likely to accidentally leak resources because you're not using the idiomatic pattern.

FMM
A: 

Managed objects will be disposed of automatically by garbage collection at some non-deterministic point in the future. However, when are working with objects that may hold unmanaged resources (not under control of the CLR / garbage collection), the IDisposable should be implemented to provide a consistent and deterministic method of returning these resources to the operating system.

The interface only provides any real benefit when the object is used within the context of a using() { ... } block. Such a block tells the CLR to call the Dispose method when it hits the closing brace of the block. So no matter what happens within this block (short of some catastrophic system failure), your Dispose method is guaranteed to be called and your unmanaged resources freed.

For instance, in the code you provided, if an exception was thrown, then your Release() method may never get called was called, potentially leaving the connection open. However, when working with a disposable object withint a using block, when the exception is thrown, the CLR will jump in and call your Dispose method before it throws the exception.

Mikey Cee