Destructors are used to instantiate an instance of a class.
Note
Destructors cannot be defined in structs. Destructors can only be used on classes.
A class can have only one destructor.
Destructors cannot be inherited or overloaded.
Destructors cannot be called. They are automatically called.
Destructors have neither modifiers nor parameters.
For example, the following is a declaration of a destructor for a class Car:
| 1234567 |
classCar{ ~Car() // destructor { // cleanup statements... }} |
The destructor implicitly calls Finalize on the base class of the object. In this way, the preceding destructor code is implicitly converted to the following code:
| 1234567891011 |
protected override Code class= "CSharp keyword" >void finalize () {   try   {    //Cleanup statements ...   }   Finally   {    base   } } |
This means that the Finalize method is called recursively (from the most derived to the least derived) to all instances in the inheritance chain.
Attention
You should not use an empty destructor. If the class contains a destructor, an item is created in the Finalize queue. When the destructor is called, the garbage collector is called to process the queue. If the destructor is empty, it will only result in an unnecessary performance penalty.
Programmers cannot control when destructors are called, because this is determined by the garbage collector. The garbage collector checks to see if there are objects that the application is no longer using. If the garbage collector considers an object to be destructor-compliant, call the destructor (if any) and reclaim the memory used to store the object. Destructors are also called when the program exits.
You can enforce garbage collection by calling Collect, but in most cases you should avoid doing this because it can cause performance problems.
Using destructors to free resources
In general, C # does not require much memory management compared to a development language that is not garbage collected at run time. This is because the. NET Framework garbage collector implicitly manages memory allocation and deallocation of objects. However, when an application encapsulates unmanaged resources such as Windows, files, and network connections, these resources should be freed using destructors. When an object conforms to a destructor, the garbage collector runs the object's Finalize method.
Explicit release of resources
If your application is using expensive external resources, we also recommend that you provide a way to explicitly release resources before the garbage collector releases objects. This can be done by implementing the Dispose method from the IDisposable interface, which performs the necessary cleanup for the object. This can greatly improve the performance of your application. Even with this explicit control over resources, destructors are a safeguard that can be used to clean up resources when a call to the Dispose method fails.
The following example creates three classes, and these three classes form an inheritance chain. Class first is the base class, Second is derived from first, and third is derived from Second. There are destructors for all three of these classes. In Main (), an instance of the most derived class is created. Note: When the program runs, the destructors for these three classes are called automatically and are called from the most derived to the least-derived order.
| 1234567891011121314151617181920212223242526272829303132 |
class First{ ~First() { System.Diagnostics.Trace.WriteLine("First‘s destructor is called."); }}class Second : First{ ~Second() { System.Diagnostics.Trace.WriteLine("Second‘s destructor is called."); }}class Third : Second{ ~Third() { System.Diagnostics.Trace.WriteLine("Third‘s destructor is called."); }}class TestDestructors{ static void Main() { Third t = new Third(); }} |
Output:
| 123 |
Third‘s destructor is called.Second‘s destructor is called.First‘s destructor is called. |
The difference between a destructor and the Dispose () method
1. Dispose requires the implementation of the IDisposable interface.
2. Dispose is called by developer Code, and destructors are called automatically by the GC.
3. The Dispose method should free all managed and unmanaged resources. Destructors should only dispose of unmanaged resources. Because the destructor is called by the GC, when the GC determines that an object is no longer needed, the destructor is called, and the object may contain other useful managed resources.
4. It is recommended to call the Dispose method by using the system GC's frequent call to destructors to release resources to reduce system performance.
5. Add code "GC" at the end of the Dispose method. SuppressFinalize (this); ", which tells the GC that it does not need to call the destructor of the object again, or that the GC will still call its destructor after judging that the object is no longer useful, although the program does not go wrong, but it affects system performance.
6. The destructor and dispose should release the same resources, so that the resource will be freed in Finalize even if the class consumer does not call Dispose.
7. Finalize should not be public.
8. When a Dispose method exists, it should be called because Finalize frees the resource is usually very slow.
The "C #" analytic destructor