A
destructor is a method which is invoked automatically when an object
is destroyed.
- Destructors are used to destruct instances of classes.
- Destructors are only used with classes. They cannot be used with structs.
- A class can only have one destructor.
- Destructors cannot be inherited or overloaded.
- Destructors cannot be called. They are invoked automatically.
- A destructor does not take modifiers or have parameters.
For
example, the following is a declaration of a destructor for the class
MyBike:
~
MyBike()
{
//
Cleanup statements.
}
The
destructor implicitly calls the Object.Finalize method on the
object's base class. Therefore, the preceding destructor code is
implicitly translated to:
protected
override void Finalize()
{
try
{
//
Cleanup statements.
}
finally
{
base.Finalize();
}
}
This
means that the Finalize method is called recursively for all
of the instances in the inheritance chain, from the most derived to
the least derived.
The
programmer has no control on when the destructor is called because
this is determined by the garbage collector. The garbage collector
checks for objects that are no longer being used by the application.
It considers these objects eligible for destruction and reclaims
their memory. Destructors are also called when the program exits.
It
is possible to force garbage collection by calling the GC.Collect
method, but in most cases, this should be avoided because it may
result in performance issues.
Example
The
following example creates three classes that make a chain of
inheritance. The class A is the base class, B is derived from A, and
C is derived from B. All three have destructors. In Main(), an
instance of the most derived class is created. When the program runs,
notice that the destructors for the three classes are called
automatically, and in order, from the most derived to the least
derived.
class
A
{
~A()
{
Console.WriteLine("A's
destructor is called");
}
}
class
B: A
{
~B()
{
Console.WriteLine("B's
destructor is called");
}
}
class
C: B
{
~C()
{
Console.WriteLine("C's
destructor is called");
}
}
public
class DestructorTester
{
public
static void Main()
{
C
myObject = new C();
}
}
Output
C's
destructor is called
B's
destructor is called
A's
destructor is called
Using
Destructors to Release Resources
In
general, you should not be as concerned about memory management
because the .NET Framework garbage collector implicitly manages the
allocation and release of memory for your objects. However, when your
application encapsulates unmanaged resources such as windows, files,
and network connections, you should use destructors to free those
resources. When the object is eligible for destruction, the garbage
collector runs the object's Finalize method.
Explicit
Release of Resources
If
your application is using an expensive external resource, it is also
recommended that you provide a way to explicitly release the resource
before the garbage collector frees the object. You do this by
implementing a Dispose method (from the IDisposable
interface) that performs the necessary cleanup for the object. This
can considerably improve the performance of the application. Even
with this explicit control over resources, the destructor becomes a
safeguard to clean up resources if the call to the Dispose method
failed.
No comments:
Post a Comment