C# Tutorial
C# String
C# Array
C# Flow Control
C# Class and Object
C# Inheritance
C# Interface
C# Collection
C# Generic
C# File I/O
C# Delegate and Event
C# Exception
C# Process and Thread
C# ADO.NET Database Operations
In C#, destructors are used to release resources held by an object when it is no longer needed, such as memory, file handles, or network connections. However, it is essential to note that C# has a garbage collector that automatically reclaims memory, so you don't need to worry about memory management in most cases.
In this tutorial, we'll cover how destructors work in C# and how to define and use them properly.
A destructor is a special method with the same name as the class, preceded by a tilde (~). It cannot have any parameters, access modifiers, or a return type.
Here's an example of a destructor for a MyClass
class:
class MyClass { // Constructor public MyClass() { Console.WriteLine("Constructor called."); } // Destructor ~MyClass() { Console.WriteLine("Destructor called."); } }
The destructor is called automatically when the garbage collector decides to release the memory occupied by the object. Since the garbage collector runs on a separate thread, you cannot predict exactly when the destructor will be called. In most cases, you don't need to worry about when or if the destructor is called.
In C#, destructors are rarely used, because the garbage collector takes care of memory management. However, if your class holds other resources, such as file handles or network connections, you might need to release those resources manually.
It is recommended to use the IDisposable interface and the using
statement for this purpose, as it provides a deterministic way to release resources. Here's an example of how to use the IDisposable interface:
using System; using System.IO; class MyResource : IDisposable { private StreamReader _reader; public MyResource(string filePath) { _reader = new StreamReader(filePath); } public void Read() { Console.WriteLine(_reader.ReadToEnd()); } public void Dispose() { Console.WriteLine("Disposing resources."); _reader.Dispose(); } } class Program { static void Main(string[] args) { using (MyResource resource = new MyResource("file.txt")) { resource.Read(); } Console.WriteLine("Resource disposed."); } }
In this example, the MyResource
class implements the IDisposable
interface and defines a Dispose()
method that releases the resources (in this case, the StreamReader). The using
statement ensures that the Dispose()
method is called when the using
block is exited, either by completing the block or by encountering an exception.
In conclusion, destructors are not commonly used in C# due to the garbage collector handling memory management. It is recommended to use the IDisposable interface and the using
statement for deterministic resource cleanup.
C# destructor example:
public class MyClass { // Destructor ~MyClass() { // Cleanup code Console.WriteLine("Destructor called!"); } }
How to define a destructor in C#:
~ClassName
syntax. It is automatically called when the object is garbage collected.public class MyClass { // Destructor ~MyClass() { // Cleanup code Console.WriteLine("Destructor called!"); } }
Explicitly implementing IDisposable with destructor in C#:
IDisposable
allows explicit resource cleanup. The destructor can be used as a failsafe in case the consumer forgets to call Dispose()
.public class MyClass : IDisposable { // Dispose method public void Dispose() { // Cleanup code Console.WriteLine("Dispose called!"); // Suppress finalization to avoid calling the destructor GC.SuppressFinalize(this); } // Destructor ~MyClass() { // Cleanup code Console.WriteLine("Destructor called!"); } }