Reputation: 103
We all know that IDisposable interface is using for disposing unmanaged resources. I have a class which contains following code. here i have implemented the Dispose method from IDisposable interface.
class ClassA:IDisposable
{
public ClassA()
{
Console.WriteLine("ClassBeingTested: Constructor");
}
private bool disposed = false;
Image img = null;
public Image Image
{
get { return img; }
}
~ClassA()
{
Console.WriteLine("ClassBeingTested: Destructor");
// call Dispose with false. Since we're in the
// destructor call, the managed resources will be
// disposed of anyways.
Dispose(false);
}
public void Dispose()
{
Console.WriteLine("ClassBeingTested: Dispose");
// dispose of the managed and unmanaged resources
Dispose(true);
// tell the GC that the Finalize process no longer needs
// to be run for this object.
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposeManagedResources)
{
// process only if mananged and unmanaged resources have
// not been disposed of.
if (!this.disposed)
{
Console.WriteLine("ClassBeingTested: Resources not disposed");
if (disposeManagedResources)
{
Console.WriteLine("ClassBeingTested: Disposing managed resources");
// dispose managed resources
if (img != null)
{
img.Dispose();
img = null;
}
}
// dispose unmanaged resources
Console.WriteLine("ClassBeingTested: Disposing unmanaged resouces");
disposed = true;
}
else
{
Console.WriteLine("ClassBeingTested: Resources already disposed");
}
}
// loading an image
public void LoadImage(string file)
{
Console.WriteLine("ClassBeingTested: LoadImage");
img = Image.FromFile(file);
}
}
What my doubt is why i need to implement the Dispose method from IDisposable interface?. Instead of that i can create my own Dispose method in my class without inheriting from IDisposable interface which i have given below.
for the class below i haven't inherited my class from IDisposable interface. instead of that i created my own dispose method. this also works fine.
class ClassA
{
public ClassA()
{
Console.WriteLine("ClassBeingTested: Constructor");
}
private bool disposed = false;
Image img = null;
public Image Image
{
get { return img; }
}
~ClassA()
{
Console.WriteLine("ClassBeingTested: Destructor");
// call Dispose with false. Since we're in the
// destructor call, the managed resources will be
// disposed of anyways.
Dispose(false);
}
public void Dispose()
{
Console.WriteLine("ClassBeingTested: Dispose");
// dispose of the managed and unmanaged resources
Dispose(true);
// tell the GC that the Finalize process no longer needs
// to be run for this object.
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposeManagedResources)
{
// process only if mananged and unmanaged resources have
// not been disposed of.
if (!this.disposed)
{
Console.WriteLine("ClassBeingTested: Resources not disposed");
if (disposeManagedResources)
{
Console.WriteLine("ClassBeingTested: Disposing managed resources");
// dispose managed resources
if (img != null)
{
img.Dispose();
img = null;
}
}
// dispose unmanaged resources
Console.WriteLine("ClassBeingTested: Disposing unmanaged resouces");
disposed = true;
}
else
{
Console.WriteLine("ClassBeingTested: Resources already disposed");
}
}
// loading an image
public void LoadImage(string file)
{
Console.WriteLine("ClassBeingTested: LoadImage");
img = Image.FromFile(file);
}
}
So can any one tel me tat the reason behind of implementing dispose method from IDisposable interface.
Upvotes: 1
Views: 725
Reputation: 81277
Three "unwritten" parts of the contract for .net objects are:
This is in general a very useful pattern. While there are some rare occasions when it will be impossible for a class to properly implement IDisposable (most commonly because the class exists to expose a complex resource whose cleanup semantics are understood by the user of the class, but not by the class itself), it's very useful to have a unified means of cleanup when things like exceptions occur.
Upvotes: 1
Reputation: 3103
IDisosable is very useful. For example working with Database connections. It requires all of its implementations to have Dispose method.
It is very useful for working with unmanaged resources, where you have to release them as for the Database connections above, because Garbage Collector is working on managed code (it releases objects where they are not in use anymore), but for unmanaged as C++ application or library (without CLR), it has no idea what is going there. By using its disposable method you say you have finished your work with such a resource and it is being released (freeing memory).
Example (example class and usage):
class Database : IDisposable
{
private SqlConnection _conn;
public Database(string conn_str)
{
// Doing the connectivity
}
public Dataset Read(string sql)
{
SqlCommand cmd = new SqlCommand();
Dataset result = null;
// etc...
return result;
}
public Dispose()
{
_conn.Close();
}
}
using(Database db = new Database(conn_string))
{
Dataset ds = db.Read("SELECT something FROM table");
}
The this approach is very useful. In this statement you init your IDisposable and at the end of statement (not needed to call db.Dispose()) its Dispose() is called and the resources are freed. In this case unmanaged resource may be the .NET SQL Driver, you can use MySQL library, etc.
Upvotes: 1
Reputation: 4806
Although implementing your own dispose method will suffice for any explicit call made to that method but when,after implementig Idispobale, you use a using statement, the built in .Net functionality will invoke your dispose method for you so your code can look like this;
using (ClassA foo = new ClassA())
{
...
}
rather than this
using (ClassA foo = new ClassA())
{
....
foo.Dispose();
}
Upvotes: 2
Reputation: 1503290
Two reasons:
IDisposable
expresses intent (this should be disposed) in a conventional manner. It's easy to spot that you should dispose of a resource if it implements IDisposable
, whereas relying on other developers to read the documentation carefully is more likely to lead to errors.That convention is used by the using
statement. You should be able to write:
using (ClassA foo = new ClassA())
{
...
}
... but unless you implement IDisposable
, you can't.
(Personally I wouldn't include a finalizer, by the way... that's usually only for directly held unmanaged resources; here you should rely on the Image
finalizer.)
Upvotes: 2
Reputation: 405
When you implement IDisposable interface you can use your class in using block, like this:
...
using(var classA = new ClassA())
{
do some stuff
}
after it your Dispose method will be invoked.
It is quite useful.
Upvotes: 1
Reputation: 23324
When you implement IDisposable
, you can use using
for exception-safe disposing.
Upvotes: 6