hello
i've read msdn and various posts about dispose pattern, and there are still a couple of things i don't understand. I've written the following code to test the dispose pattern. Please note that there aren't unmanged resources, i'm using vs2008 and .net 3.5 :
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void tryDispose()
{
//test 1 : allocate resource and leave manage it to gc
BL.myclass df = new BL.myclass();
//test 2 : try to force garbage collecting
//GC.Collect();
//test 3 : call dispose myself
//using (BL.myclass df = new BL.myclass())
//{
//}
}
private void button1_Click(object sender, EventArgs e)
{
tryDispose();
}
this is my disposable class:
class myclass: IDisposable
{
private StronglyTypedDs myDS;
private bool _disposed;
public myclass()
{
using (myDSTableAdapter docDocadpt = new myDSTableAdapter())
{
myDS = new StronglyTypedDs();
docDocadpt.Fill(myDS.TheTable);
}
}
#region IDisposable Members
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~myclass()
{
Dispose(false);
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
if (myDS != null)
myDS .Dispose();
myDS = null;
}
}
_disposed = true;
}
#endregion
}
The results are :
test 1a - just instantiating myclass, the destructor is commentend since myclass doesn't contains unmanaged resources : myclass.dispose is not called, even if i close the application (whose dispose is executed instead) . So what's the state of the dataset once i close the application ?
test 1b - uncommenting destructor, it's ok all disposes are called when i close the application.
test 2a and 2b - i do the above test just calling gc.collect : the behaviour is identical to test 1a and 1b respectively
test 3 - everything works fine (of course)
many posts says that, if myclass doesn't contains unmanaged resources, i don't need to add the destructor; yet in my tests , if i don't add the destructor , myclass.dispose doesn't get called when i close the application. I haven't waited for the gc to run by itself (if i remember correctly gc.collect doesn't guarantes the class instance is deallocated) to check if it will call myclass.dispose . So what's the correct implemention : always define e destructor or avoid it if myclass contains only managed resources ? If i had filled all generations levels, would had the gc called myclass dispose or not without having implemented a destructor?
Finally i've noticed that if i define a destructor , but don't declare the class as implementing IDisposable, the disposing chain works anyway. This could make sense since the destructor might be translated to finalize in IL. But i find it really confusing : is it some kind of "implicit" interface implementation i don't know? gc can dispose the item but users can't
thank you in advance
Stefano