Reputation: 399
I have created a generic DAO factory. The factory class implements IDisposable.
I want to create a destructor for this generic class, so that it implements IDisposable correctly.
How can I define destructor for this generic class? Is it even necessary or should I leave the implementation of IDispoable and destructor to its non-generic base classes?
Upvotes: 0
Views: 764
Reputation: 1483
There're some keys about from the book MCSD Certification Toolkit (exam 70-483) pag 193:
destructor ≈(it's almost equal to) base.Finalize(), The destructor is converted into an override version of the Finalize method that executes the destructor’s code and then calls the base class’s Finalize method. Then its totally non deterministic you can't able to know when will be called because depends on GC.
If a class contains no managed resources and no unmanaged resources, it doesn’t need to implement IDisposableor have a destructor.
If the class has only managed resources, it should implement IDisposable but it doesn’t need a destructor. (When the destructor executes, you can’t be sure managed objects still exist, so you can’t call their Disposemethods anyway.)
If the class has only unmanaged resources, it needs to implement IDisposableand needs a destructor in case the program doesn’t call Dispose.
The Dispose method must be safe to run more than once. You can achieve that by using a variable to keep track of whether it has been run before.
The Dispose method should free both managed and unmanaged resources.
The destructor should free only unmanaged resources. (When the destructor executes, you can’t be sure managed objects still exist, so you can’t call their Disposemethods anyway.)
After freeing resources, the destructor should call GC.SuppressFinalize, so the object can skip the finalization queue.
An Example of a an implementation for a class with unmanaged and managed resources:
using System;
class DisposableClass : IDisposable
{
// A name to keep track of the object.
public string Name = "";
// Free managed and unmanaged resources.
public void Dispose()
{
FreeResources(true);
}
// Destructor to clean up unmanaged resources
// but not managed resources.
~DisposableClass()
{
FreeResources(false);
}
// Keep track if whether resources are already freed.
private bool ResourcesAreFreed = false;
// Free resources.
private void FreeResources(bool freeManagedResources)
{
Console.WriteLine(Name + ": FreeResources");
if (!ResourcesAreFreed)
{
// Dispose of managed resources if appropriate.
if (freeManagedResources)
{
// Dispose of managed resources here.
Console.WriteLine(Name + ": Dispose of managed resources");
}
// Dispose of unmanaged resources here.
Console.WriteLine(Name + ": Dispose of unmanaged resources");
// Remember that we have disposed of resources.
ResourcesAreFreed = true;
// We don't need the destructor because
// our resources are already freed.
GC.SuppressFinalize(this);
}
}
}
Upvotes: 1