Updated July 5, 2023
Introduction to Destructor in C#
In the article Destructor in C# as the name suggests, destructors are the methods in C# which destroy the objects. If the objects are no longer required, then the destructor is called to destroy those objects from the class. The destructor will invoke automatically by the garbage collector and destroys objects.
Syntax:
class Demo
{
// other methods
~Demo() // destructor
{
// your code
}
}
C# destructor is a shortcut of Finalize( ) method. So when you declare destructor
~Demo() // destructor
{
// your code
}
C# compiler will translate it to:
protected override void Finalize()
{
try
{
// your code
}
finally
{
base.Finalize();
}
}
Destructor is represented by ~ (tilde).
Properties of Destructor in C#
The following are the properties of destructor:
- Destructors cannot have any parameters and access modifiers.
- Each class should consist of only one destructor.
- Destructors cannot be overloaded or inherited.
- The destructor name is always the same as the class name and has no return type.
- Destructor uses the Finalize method and invoked by Garbage Collector when objects are no longer required.
- Destructor follows the reverse pattern. In the destructor, the derived class is called first and then base class.
How does Destructor work in C#?
Here are some examples which show how it works in C#.
Example #1
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Destructor
{
class person
{
//variables
public string name;
public int age;
public person(string name,int age) //parametrized constructor
{
this.name = name;
this.age = age;
}
public string getName()
{
return this.name;
}
public int getAge()
{
return this.age;
}
~person() // destructor
{
Console.WriteLine("Destructor has been invoked");
}
}
class Program
{
// main method
static void Main(string[] args)
{
person Details = new person("Joe", 28);
Console.WriteLine(Details.getName());
Console.WriteLine(Details.getAge());
}
}
}
In the above example, the parameterized constructor is initialized with parameter name and age where this is a keyword referring to class variables. After that destructor is created with the same name as the class name and symbol ~. In the main method, there is an object of the class person. After getting a person’s name and age, objects are no longer required. So destructor is being called which destroys the objects and de-allocate their memories.
Output:
Example #2
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
anmespace Destructor
{
class person
{
// variables
public string name;
public int age;
public person(string name,int age) // parameterized constructor
{
this.name = name;
this.age = age;
}
public string getName()
{
return this.name;
}
public int getAge()
{
return this.age;
}
~person() //destructor
{
Console.WriteLine("Descructor has been invoked");
}
}
class Program
{
// Main method
static void Main(string[] args)
{
person Details = new person("Joe", 28); // first object
person Details1 = new person("John", 20);
Console.WriteLine(Details.getName());
Console.WriteLine(Details.getAge());
Console.WriteLine(Details1.getName());
Console.WriteLine(Details1.getAge());
}
}
}
This example is almost the same as the previous example, but in this example, there are two objects in the main method. As we know, the constructor runs for every object and this same thing is applied to the destructor also. In this case, the destructor is being called two times and de-allocates the memory of each object.
Output:
Example #3
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Destructor
{
public class Parent
{
~Parent() // base destructor
{
Console.WriteLine("Parent.~Parent()");
}
}
public class Child : Parent
{
~Child() // derived destructor
{
Console.WriteLine("Child.~Child()");
}
}
public class MainClass
{
static void Main()
{
Child child = new Child();
}
}
}
In the above example, the parent class is defined which has a destructor. Then the child class inherits parent class and consists of a destructor too. So child destructor automatically calls the base destructor.
In constructors, the base constructor is called first. For example, if we have base class A which is inherited by class B so in case of constructor class A is called first and then class B. However, in the case of destructor class B (derived class) is called first before class A (base class).
Another example of order execution:-
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Destructor
{
class Tree
{
~Tree()
{
System.Console.WriteLine("This is the first destructor");
}
}
class Branch: Tree
{
~Branch()
{
System.Console.WriteLine("This is the second destructor");
}
}
class Flower: Branch
{
~Flower()
{
System.Console.WriteLine("This is the third destructor");
}
}
class Test
{
static void Main()
{
Flower f= new Flower();
}
}
}
Output:
As you can see, the third constructor is called initially followed by the second and the first.
Example #4
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Destructor
{
class Example
{
public Example()
{
// constructor
Console.WriteLine("Object Created");
}
// Destructor
~Example()
{
Console.WriteLine("Object Destroyed");
}
}
class Program
{
public static void Sample()
{
Example ex = new Example();
}
static void Main(string[] args)
{
Sample();
GC.Collect();
Console.ReadLine();
}
}
}
Output:
Destructor de-allocates the memory of the object if they are not required at the end of the program. But sometimes if we use GC.Collect() in the middle of program execution, it will destroy objects in the middle and de-allocates the memory of those objects. Destructor can be called implicitly or explicitly. But there is no need to destroy the objects explicitly as C# provides garbage collection. However, when you are done with the unmanaged resources, you will need to free them explicitly. There is no need to called or case of managed resources. Use destructor for handling unmanaged resources. A garbage Collector will call a destructor as it consists of a list of objects that have a destructor. So whenever an object is created or destroyed, that list is updated. If there is an object in the queue, it is collected by the garbage collector after the destructor executes.
Conclusion
The main purpose of the destructor is to free the memory of objects after their execution. So there are different actions executed in the destructor like recovering the space, releasing network resources and resource locks, etc. Destructors should be used to release unmanaged resources rather than managed resources.
Recommended Article
This has been a guide to Destructor in C#. Here we discuss the introduction, properties as well as Examples of Destructor in C#. You can also go through our other suggested articles to learn more –