Destructors in C #
by Ansil
Introduction
In the Enterprise application development world, the buzzwords are performance, scalability, and security. I started my career as a VC programmer, and one fine morning, I was transferred to WEB Development department. Like every C + + programmer, I also was frustrated. I thought every Tom, Dick, and our very own Harry can program in HTML. But, soon I found that the real challenge are to produce high performance, scalable, and reliable applications. And above all this loosely coupled, stateless nature of web environment are always going to haunt.
In the order to produce the high performance scalable applications, it's important to use your the optimized resources. One tip is this use your resource as late as your can and free it in the earliest after your use. My intention are to describe the object cleaning up mechanism used in C #. Destructors
As we know, ' destructors ' are used to destruct instances of classes. When we are are using destructors in C #, we have to keep in mind the following Things: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.
The following is a declaration of a destructor for the class MyClass:
{
Cleaning up code goes here
}
The programmer has no control in when the destructor is going to was executed because this is determined by the garbage Col Lector. The garbage collector checks for objects this are no longer being by the used. It considers these objects eligible for destruction and reclaims their. Destructors are also called the program exits. When a destructor executes what are happening behind the scenes is this destructor implicitly the calls method on the object ' s base class. Therefore, the preceding destructor code is implicitly translated to:
protected override void Finalize ()
{
Try
{
Cleaning up.
}
Finally
{
Base. Finalize ();
}
}
Now, let us look at a example of how destructors are called. We have three classes A, B and C. B are derived from A, and C are derived from B. Each class has their own constructors and destructors. In the main's class App, we create an object of C.
using System;
Class A
{
public A ()
{
Console.WriteLine ("Creating a");
}
~a ()
{
Console.WriteLine ("Destroying A");
}
}
class b:a
{
Public B ()
{
Console.WriteLine ("Creating B");
}
~b ()
{
Console.WriteLine ("Destroying B");
}
}
Class C:b
{
Public C ()
{
Console.WriteLine ("Creating C");
}
~c ()
{
Console.WriteLine ("Destroying C");
}
}
Class App
{
public static void Main ()
{
C c=new C ();
Console.WriteLine ("Object Created");
Console.WriteLine ("Press ENTER to Destroy it");
Console.ReadLine ();
C=null;
//GC. Collect ();
Console.read ();
}
}
As we expect, the constructors of base classes is executed and program'll wait for the user to press ' enter '. When this is occurs, we set the object of class C to null. But the destructors are not executing.!!?? As we already said, the programmer has no control in when the destructor was going to be executed because the garbage colle ctor determines this. But the destructors are called the program exits. You can check this by redirecting the o/p of the program to a text file. I have the output here. Notice that the destructors of the base classes are called because behind the scenes base. Finalize () is called.
Creating A
Creating B
Creating C
Press ENTER to Destroy it
Destroying C
Destroying B
Destroying A
So, what does if you are want to call the destructors once you are the using the object? There are two ways:call the garbage. Implement Dispose method of IDisposable interface. calling the garbage collector
You can force the garbage collector of the the GC by calling. Collect method, the But in most cases, this should is avoided because it may result in performance issues. In the above program, remove the comment on GC. Collect (). Compile and run it. Now, you can have a destructors being executed in the console itself. implement IDisposable interface.
The IDisposable interface contains only one of public method with signature void Dispose (). We can implement this method to close or release unmanaged such as files, streams, and handles held by a Instan Ce of the class that implements this interface. This is used to all tasks associated with freeing to held by a object. When implementing this method, objects must seek to ensure so all held resources are freed through propagating the call Throu GH the containment hierarchy.
Class Myclass:idisposable
{
public void Dispose ()
{
Implementation
}
}
When we are implement IDisposable interface, we require discipline to ensure this is called. Using the destructor and IDisposable interface together
public class Myclass:idisposable
{
private bool Isdisposed=false;
public void Dispose ()
{
Dispose (TRUE);
Gc. Supressfinalize (this);
}
protected void Dispose (bool diposing)
{
if (! isdisposed)
{
if (disposing)
{
Clean up Managed resources
}
Clean Up Unmanaged Resources
}
Isdisposed=true;
}
~myclass ()
{
Dispose (FALSE);
}
}
Here the overload of Dispose (BOOL) does the "cleaning up" and "all" cleaning up code are written only in this method. This are called by both the destructor and the IDisposable.Dispose (). We should take care that this Dispose (bool) is not called from any where else except () and the destructor.
When a client calls IDisposable.Dispose (), then the client deliberately wants to clean up the managed and unmanaged Resour CE, and so the cleaning-is-done. One thing you must have noticed are that we called GC. Supressfinalize (this) immediately after we cleaned up the resource. This method tells the garbage Collector that there are no need to call its destructor because we have do the already N Up.
Notice that in the above example, the destructor calls the Dispose with parameter as false. Here we are are ensuring that the garbage collector collects the managed. We are only doing the cleaning up of unmanaged resource. Conclusion
Even though we have spent some time implementing the IDisposable interface, what if the client doesn ' t call them properly? C # has a cool solution for this. The ' using ' block. It looks like this:
using (MyClass objcls =new MyClass ())
{
}
When the "control" exits from the "using block either by running successfully and reaching" closing braces or by throwing An exception, the Idispose.dispose () of MyClass would be executed. Remember the object you instantiate must implement the System.IDisposable interface. The using statement defines a scope at the "end of which" an object would be disposed. About Ansil
|
Ansil is a MCAD in. NET and his hails from Trivandrum. He is a independent consultant and has got software development experiences in asp.net, MFC, Visual C #, ASP, SQL Server2 , C # webservices, COM + and XML. He spends his time reading technical articles, searching the net for latest news about various Technologies,and he plays C Ricket and has a passion of watching horror movies.
"The They ignore you;then they laugh at your then they fight you; then win"Click here to view Ansil's online profile. |