ุจู†ู‚ูˆู„ ุนู„ูŠู‡ ุงู„ู‡ุงุฏู…ูŠู† ุงูˆ ุงู„ู„ูŠ ุจูŠูƒุณุฑูˆุง ุงู„ู„ูŠ ู‡ู…ุง ุงู„ู€ Destructors

What are Destructors in C#?

ุงู„ู€ Destructors ุงู„ู„ูŠ ุจูŠุชุณู…ูˆุง ุจุฑุถู‡ Finalizers ููŠ C# ุจูŠูุณุชุฎุฏู…ูˆุง ุนุดุงู† ู†ู†ุธู ุงู„ูƒู„ุงุณ ุจุชุงุนู†ุง ู„ู…ุง class instance ู…ุนูŠู† ุจูŠุชุฌู…ุน ููŠ ุงู„ู€ garbage collector.

ุงู„ู€ Destructor ู‡ูˆ ุจุฑุถู‡ method ุฎุงุตุฉ ู…ูˆุฌูˆุฏุฉ ููŠ ุงู„ู€ classุŒ ุฒูŠ ุงู„ู€ constructor ุจุงู„ุธุจุทุŒ ูˆู„ูŠู‡ุง ู†ูุณ ุงุณู… ุงู„ู€ class ู„ูƒู† ู‚ุจู„ู‡ุง ุนู„ุงู…ุฉ ~ (tilde).

  • ุงู„ู€ Constructor ููŠ C# ุจูŠุชู†ุฏู‡ู„ู‡ ุตุฑุงุญุฉู‹ (Explicitly) ู„ู…ุง ุจู†ุนู…ู„ object ู…ู† ุงู„ู€ class.
  • ุงู„ู€ Destructor ููŠ C# ุจูŠุชู†ุฏู‡ู„ู‡ ุถู…ู†ูŠู‹ุง (Implicitly) ู„ู…ุง ุงู„ู€ object ุจูŠุชุฏู…ุฑ.

ุนุดุงู† ู†ูุฑู‚ ุจูŠู† ุงู„ู€ Constructor ูˆุงู„ู€ Destructor ุจู…ุง ุฅู† ู„ูŠู‡ู… ู†ูุณ ุงู„ุงุณู…ุŒ ุจู†ุณุชุฎุฏู… ุนู„ุงู…ุฉ ุงู„ู€ (~) ู‚ุจู„ ุงุณู… ุงู„ู€ destructor method. ุงู„ู€ syntax ุจุชุงุนู‡ ูƒุงู„ุชุงู„ูŠ:

class MyClass
{
    // Destructor
    ~MyClass()
    {
        // Cleanup code
    }
}

ู…ู„ุญูˆุธุฉ: ุฃู‡ู… ู†ู‚ุทุฉ ู„ุงุฒู… ุชูุชูƒุฑู‡ุง ู‡ูŠ ุฅู† ุงู„ู€ destructor method ู…ูŠู†ูุนุด ูŠูƒูˆู† ู„ูŠู‡ุง ุฃูŠ parameters ูˆู„ุง ูŠู†ูุน ู†ุทุจู‚ ุนู„ูŠู‡ุง ุฃูŠ modifiers. ูˆุจู…ุง ุฅู†ู‡ุง ู…ู† ุบูŠุฑ parametersุŒ ูู…ุด ู…ู…ูƒู† ู†ุนู…ู„ู‡ุง overloading.

When is a Destructor method Called in C#?

ุงู„ู€ Destructor method ุจูŠุชู†ุฏู‡ู„ู‡ุง ุชู„ู‚ุงุฆูŠู‹ุง ุจูˆุงุณุทุฉ ุงู„ู€ garbage collector ู„ู…ุง ุงู„ู€ object ุจุชุงุน ุงู„ู€ class ุจูŠุชุฏู…ุฑ. ูุงู„ู†ู‚ุทุฉ ุงู„ู„ูŠ ู„ุงุฒู… ุชูุชูƒุฑู‡ุง ู‡ูŠ ุฅู† ุงู„ู€ destructors ุจุชุชู†ุฏู‡ ุชู„ู‚ุงุฆูŠู‹ุง.

When will the Object of a Class get Destroyed in C#?

ุงู„ู€ object ุจุชุงุน ุงู„ู€ class ููŠ C# ุจูŠุชุฏู…ุฑ ูˆุจูŠุชุดุงู„ ู…ู† ุฎู„ุงู„ ุงู„ู€ garbage collector ููŠ ุฃูŠ ุญุงู„ุฉ ู…ู† ุงู„ุญุงู„ุงุช ุฏูŠ:

  1. ููŠ ู†ู‡ุงูŠุฉ ุชู†ููŠุฐ ุงู„ุจุฑู†ุงู…ุฌุŒ ูƒู„ object ู…ุฑุชุจุท ุจุงู„ุจุฑู†ุงู…ุฌ ุจูŠุชุฏู…ุฑ.
  2. ู„ู…ุง ุงู„ู€ garbage collector ูŠุดุชุบู„ ุจุดูƒู„ ุถู…ู†ูŠ ููŠ ู†ุต ุชู†ููŠุฐ ุงู„ุจุฑู†ุงู…ุฌ ู„ูˆ ุงู„ุฐุงูƒุฑุฉ ุงุชู…ู„ุชุŒ ูˆุณุงุนุชู‡ุง ุจูŠุญุฏุฏ ุงู„ู€ objects ุบูŠุฑ ุงู„ู…ุณุชุฎุฏู…ุฉ ูˆูŠุฏู…ุฑู‡ุง.
  3. ู„ู…ุง ุงู„ู…ุจุฑู…ุฌ ูŠุณุชุฏุนูŠ ุงู„ู€ garbage collector ุจุดูƒู„ ุตุฑูŠุญ ููŠ ู†ุต ุชู†ููŠุฐ ุงู„ุจุฑู†ุงู…ุฌ ุจุงุณุชุฎุฏุงู… GC.Collect()ุŒ ูˆุณุงุนุชู‡ุง ุฃูŠ objects ุบูŠุฑ ู…ุณุชุฎุฏู…ุฉ ุจุชุฏู…ุฑ.

Example to Understand Destructors in C#

using System;
namespace DestructorExample
{
    class DestructorDemo
    {
        public DestructorDemo()
        {
            Console.WriteLine("Constructor Object Created");
        }
        ~DestructorDemo()
        {
            string type = GetType().Name;
            Console.WriteLine($"Object {type} is Destroyed");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            DestructorDemo obj1 = new DestructorDemo();
            DestructorDemo obj2 = new DestructorDemo();
            // Making obj1 eligible for Garbage Collection
            obj1 = null;
            Console.ReadKey();
        }
    }
}

ููŠ ุงู„ู…ุซุงู„ ุฏุงุŒ ุนู…ู„ู†ุง class ุงุณู…ู‡ DestructorDemo ููŠู‡ constructor ูˆ destructor. ุจุนุฏูŠู† ุฌูˆู‡ ุงู„ู€ Main methodุŒ ุนู…ู„ู†ุง ุงุชู†ูŠู† instances ู…ู† ุงู„ู€ class ุฏู‡ ูˆุฎู„ูŠู†ุง ู‚ูŠู…ุฉ obj1 ุจู€ null ุนุดุงู† ูŠุจู‚ู‰ ู…ุคู‡ู„ ู„ู„ู€ garbage collection.

ู„ู…ุง ุชุดุบู„ ุงู„ูƒูˆุฏ ุฏู‡ุŒ ู‡ุชู„ุงู‚ูŠ ุงู„ู†ุงุชุฌ ูƒุฏู‡:

Constructor Object Created
Constructor Object Created

ู‡ุชู„ุงุญุธ ุฅู† ุงู„ุฌู…ู„ ุงู„ู„ูŠ ุฌูˆู‡ ุงู„ู€ destructor ู…ุทุจุนุชุด. ู…ู…ูƒู† ุชูุชูƒุฑ ุฅู† ุงู„ู€ destructor ู…ุชู†ูุฐุด ุญุชู‰ ุจุนุฏ ู…ุง ุฎู„ูŠู†ุง obj1 ุจู€ null. ุฏู‡ ู…ุด ุตุญ. ุงู„ู†ู‚ุทุฉ ุงู„ู„ูŠ ู„ุงุฒู… ุชูุชูƒุฑู‡ุง ู‡ูŠ ุฅู† ุงู„ู€ destructor ุจูŠุชู†ุฏู‡ู„ู‡ ุถู…ู†ูŠู‹ุง ุจูˆุงุณุทุฉ ุงู„ู€ garbage collectorุŒ ูˆุฅุญู†ุง ู…ุด ุจู†ู‚ุฏุฑ ู†ุชูˆู‚ุน ุงู…ุชู‰ ู‡ูŠู†ุฏู‡ู„ู‡. ุนุดุงู† ูƒุฏู‡ ู…ุด ุจุชุดูˆู ุฌู…ู„ ุงู„ุทุจุงุนุฉ ููŠ ุงู„ู†ุงุชุฌ.

ู„ูˆ ุนุงูŠุฒุŒ ุชู‚ุฏุฑ ุชุณุชุฏุนูŠ ุงู„ู€ garbage collector ุจุดูƒู„ ุตุฑูŠุญ ุนุดุงู† ูŠุฏู…ุฑ ุงู„ู€ objects ุบูŠุฑ ุงู„ู…ุณุชุฎุฏู…ุฉ. ุนุดุงู† ู†ุนู…ู„ ูƒุฏู‡ุŒ ุจู†ุณุชุฎุฏู… GC.Collect().

// ... inside Main method
obj1 = null;
GC.Collect(); // Force garbage collection
Console.ReadKey();

Output:

Constructor Object Created
Constructor Object Created
Object DestructorDemo is Destroyed

ุฏู„ูˆู‚ุชูŠ ุชู‚ุฏุฑ ุชุดูˆู ุฅู† ุงู„ู€ Destructor ุงุชู†ูุฐ ู…ุฑุฉ ูˆุงุญุฏุฉ. ุฏู‡ ู„ุฃู†ู†ุง ุฎู„ูŠู†ุง ู‚ูŠู…ุฉ obj1 ุจุณ ุจู€ null. ู„ูˆ ุฎู„ูŠู†ุง ุงู„ุงุชู†ูŠู† objects ุจู€ nullุŒ ุงู„ู€ destructor ู‡ูŠุชู†ูุฐ ู…ุฑุฉ ู„ูƒู„ ูˆุงุญุฏ.

// ... inside Main method
obj1 = null;
obj2 = null;
GC.Collect();
Console.ReadKey();

Output:

Constructor Object Created
Constructor Object Created
Object DestructorDemo is Destroyed
Object DestructorDemo is Destroyed

Can you prove the destructor method is Implicitly called by Garbage Collector?

ู…ุซุงู„ ุจุณูŠุท

using System;
namespace DestructorExample
{
    class DestructorDemo
    {
        public DestructorDemo()
        {
            Console.WriteLine("DestructorDemo Object Created");
        }
        ~DestructorDemo()
        {
            Console.WriteLine("DestructorDemo Object Destroyed");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Main Method Execution Started");
            DestructorDemo obj1 = new DestructorDemo();
            
            obj1 = null;
            GC.Collect();
            Console.WriteLine("Some Statement Executed Inside Main Method");
            obj1 = null; // Redundant, already null
            GC.Collect();
            Console.WriteLine("Some More Statement Executed Inside Main Method");
            GC.Collect();
            Console.WriteLine("Main Method Execution End");
            Console.ReadKey();
        }
    }
}

ุฌูˆู‡ ุงู„ู€ Main methodุŒ ุนู…ู„ู†ุง instance ูˆุจุนุฏูŠู† ุฎู„ูŠู†ุงู‡ null ูˆุงุณุชุฏุนูŠู†ุง GC.Collect() ุชู„ุงุช ู…ุฑุงุช. ู„ุงุญุธ ุงู„ู€ destructor ุงุชู†ูุฐ ูƒุงู… ู…ุฑุฉ ูˆุงู…ุชู‰.

Output:

Main Method Execution Started
DestructorDemo Object Created
DestructorDemo Object Destroyed
Some Statement Executed Inside Main Method
Some More Statement Executed Inside Main Method
Main Method Execution End

ุงู„ู€ destructor ุงุชู†ูุฐ ู…ุฑุฉ ูˆุงุญุฏุฉ ุจุณุŒ ุจุนุฏ ุฃูˆู„ ู…ุฑุฉ ุงุณุชุฏุนูŠู†ุง ููŠู‡ุง GC.Collect(). ูˆุฏู‡ ุจูŠุซุจุช ุฅู† ุงู„ู€ GC ู‡ูˆ ุงู„ู„ูŠ ุจูŠุฏู…ุฑู‡ ู„ู…ุง ุจูŠู„ุงู‚ูŠู‡ ุบูŠุฑ ู…ุณุชุฎุฏู…ุŒ ูˆู…ุด ุจูŠุชุฃุซุฑ ุจุงู„ู€ Calles ุงู„ูƒุชูŠุฑ ู„ู„ู€ Collect.

Points to Remember while working with Destructors in C#

  • ุงู„ู€ Point 1: ุงู„ู€ Destructors (ุฃูˆ Finalizers) ู…ูŠู†ูุนุด ุชุชุนุฑู ููŠ structs. ุจุชุณุชุฎุฏู… ุจุณ ู…ุน ุงู„ู€ classes.
  • ุงู„ู€ Point 2: ููŠ ุงู„ู€ class ุงู„ูˆุงุญุฏุŒ ู†ู‚ุฏุฑ ู†ุนุฑู‘ู Destructor ูˆุงุญุฏ ุจุณ. ูŠุนู†ูŠ ู…ุด ู…ู…ูƒู† ู†ุนู…ู„ู‡ู… overloading.
  • ุงู„ู€ Point 3: ุงู„ู€ Destructors ู…ูŠู†ูุนุด ู†ุณุชุฏุนูŠู‡ุง ุตุฑุงุญุฉู‹. ุจูŠุชู†ุฏู‡ู„ู‡ุง ุชู„ู‚ุงุฆูŠู‹ุง ุจูˆุงุณุทุฉ ุงู„ู€ garbage collector. ุฃู‚ุตู‰ ุญุงุฌุฉ ู†ู‚ุฏุฑ ู†ุนู…ู„ู‡ุง ู‡ูŠ ุฅู†ู†ุง ู†ุทู„ุจ ู…ู† ุงู„ู€ GC ูŠู†ูุฐู‡ุง ุนู† ุทุฑูŠู‚ GC.Collect().
  • ุงู„ู€ Point 4: ุงู„ู€ Destructor ู…ุด ุจูŠุงุฎุฏ ุฃูŠ modifiers ูˆู„ุง ุฃูŠ parameters.

How Destructors are Implemented in C#?

ู„ู…ุง ุจุชูƒุชุจ destructor ููŠ C# ุจุงู„ุดูƒู„ ุฏู‡:

~Sample()
{
    // ...
}

ุงู„ู€ compiler ุจูŠุชุฑุฌู… ุฏู‡ ุถู…ู†ูŠู‹ุง ู„ู€ override ู„ู„ู€ Finalize method ุงู„ู„ูŠ ู…ูˆุฌูˆุฏุฉ ููŠ Object class ุงู„ุฃุณุงุณูŠ. ุงู„ูƒูˆุฏ ุจุชุงุนูƒ ุจูŠุชุญุท ุฌูˆู‡ try...finally ุจู„ูˆูƒ.

protected override void Finalize()
{
    try
    {
        // Your destructor code goes here
    }
    finally
    {
        base.Finalize(); // Calls the parent's Finalize method
    }
}

ุงู„ุชุตู…ูŠู… ุฏู‡ ู…ุนู†ุงู‡ ุฅู† ุงู„ู€ Finalize method ุจูŠุชู†ุฏู‡ู„ู‡ุง (recursively) ู„ูƒู„ ุงู„ู€ instances ููŠ ุณู„ุณู„ุฉ ุงู„ูˆุฑุงุซุฉุŒ ู…ู† ุฃูƒุชุฑ class ู…ุดุชู‚ (most-derived) ู„ุฃู‚ู„ ูˆุงุญุฏ (least-derived). ุฎู„ูŠู†ุง ู†ูู‡ู… ุฏู‡ ุจู…ุซุงู„.

ููŠ ุงู„ู…ุซุงู„ ุงู„ู„ูŠ ุชุญุชุŒ ุนู†ุฏู†ุง ุชู„ุงุชุฉ classes ุจูŠุนู…ู„ูˆุง ุณู„ุณู„ุฉ ูˆุฑุงุซุฉ. First ู‡ูˆ ุงู„ู€ baseุŒ ูˆ Second ุจูŠูˆุฑุซ ู…ู† FirstุŒ ูˆ Third ุจูŠูˆุฑุซ ู…ู† Second. ูˆุงู„ุชู„ุงุชุฉ ููŠู‡ู… destructors.

using System;
namespace DestructorExample
{
    public class First { ~First() { Console.WriteLine("Destructor of First Called"); } }
    public class Second : First { ~Second() { Console.WriteLine("Destructor of Second Called"); } }
    public class Third : Second { ~Third() { Console.WriteLine("Destructor of Third Called"); } }
 
    class Program
    {
        static void Main(string[] args)
        {
            Third obj = new Third();
            obj = null;
            GC.Collect();
            Console.ReadKey();
        }
    }
}
graph TD
    A[First] --> B[Second]
    B --> C[Third]
    subgraph Destruction Order
        direction BT
        D[First Destroyed] --> E[Second Destroyed]
        E --> F[Third Destroyed]
    end

Output:

Destructor of Third Called
Destructor of Second Called
Destructor of First Called

ู…ู„ุญูˆุธุฉ 1: ุงู„ู€ Destructors ุงู„ูุงุถูŠุฉ ุงู„ู…ูุฑูˆุถ ู…ู†ุชุณุชุฎุฏู…ู‡ุงุด. ู„ู…ุง class ูŠูƒูˆู† ููŠู‡ destructorุŒ ุจูŠุฏุฎู„ ููŠ Finalize queue. ุงู„ู€ queue ุฏู‡ ู‡ูˆ ุงู„ู„ูŠ ุงู„ู€ garbage collector ุจูŠุชุนุงู…ู„ ู…ุนุงู‡. ูˆุฌูˆุฏ destructors ุบูŠุฑ ุถุฑูˆุฑูŠุฉ ุจูŠุณุจุจ ุฃุฏุงุก ู…ุด ูƒูˆูŠุณ.

ู…ู„ุญูˆุธุฉ 2: ูƒู…ุทูˆุฑูŠู†ุŒ ู…ุนู†ุฏู†ุงุด ุชุญูƒู… ููŠ ุงู…ุชู‰ ุงู„ู€ destructor ุจูŠุชู†ุฏู‡ู„ู‡. ุงู„ู€ GC ู‡ูˆ ุงู„ู„ูŠ ุจูŠู‚ุฑุฑ. ู…ู…ูƒู† ู†ุฌุจุฑู‡ ูŠุดุชุบู„ ุจุงุณุชุฎุฏุงู… GC.CollectุŒ ู„ูƒู† ููŠ ู…ุนุธู… ุงู„ุฃูˆู‚ุงุช ุงู„ู…ูุฑูˆุถ ู†ุชุฌู†ุจ ุฏู‡ ู„ุฃู†ู‡ ู…ู…ูƒู† ูŠุฃุซุฑ ุนู„ู‰ ุงู„ุฃุฏุงุก.

When to use Destructor in C#?

ู…ู…ูƒู† ุชุณุฃู„ ู†ูุณูƒุŒ ู„ูˆ Memory Management ุจุชุชู… ุชู„ู‚ุงุฆูŠู‹ุงุŒ ุงู…ุชู‰ ุจู†ุญุชุงุฌ ู†ุณุชุฎุฏู… DestructorุŸ ุจุดูƒู„ ุนุงู…ุŒ ูƒู…ุทูˆุฑูŠู† C#.NETุŒ ู…ุด ู…ุญุชุงุฌูŠู† ู†ู‚ู„ู‚ ุฃูˆูŠ ู…ู† Memory Management.

ู„ูƒู†ุŒ ู„ู…ุง ุงู„ุชุทุจูŠู‚ ุจุชุงุนู†ุง ุจูŠุชุนุงู…ู„ ู…ุน unmanaged resources (ู…ูˆุงุฑุฏ ุบูŠุฑ ู…ูุฏุงุฑุฉ)ุŒ ุฒูŠ FilesุŒ ูˆNetworkุŒ ุงู„ู…ูุฑูˆุถ ู†ุณุชุฎุฏู… destructor ุนุดุงู† ู†ูุถูŠ ุงู„ู…ูŠู…ูˆุฑูŠ ู„ู„ู…ูˆุงุฑุฏ ุฏูŠ.

using System;
namespace FileHandlingDemo
{
    public class UnmanagedResource
    {
        public UnmanagedResource()
        {
            // Creating Unmanaged Resources  
            Console.WriteLine("Unmanaged Resource Created");
        }
        ~UnmanagedResource()
        {
            // Clean up Unmanaged Resources  
            Console.WriteLine("Unmanaged Resource Destroyed");
        }
    }
    class Program
    {
        static void Main()
        {
            UnmanagedResource resource = new UnmanagedResource();
            Console.WriteLine("Using Unmanaged Resource");
            resource = null;
            GC.Collect();
            
            Console.ReadKey();
        }
    }
}

Output:

Unmanaged Resource Created
Using Unmanaged Resource
Unmanaged Resource Destroyed

Explicit Release of Resources using Dispose Pattern in C#

ู„ูˆ ุชุทุจูŠู‚ูƒ ุจูŠุณุชุฎุฏู… resource ุฎุงุฑุฌูŠ ุชู‚ูŠู„ุŒ ุจูŠู†ุตุญ ุจุฅู†ูƒ ุชูˆูุฑ ุทุฑูŠู‚ุฉ ุตุฑูŠุญุฉ ุนุดุงู† ุชูุถูŠู‡ุง ุงูˆ ุชู‚ูู„ู‡ุง ุงู„ู€ resource ุฏู‡ ู‚ุจู„ ู…ุง ุงู„ู€ garbage collector ูŠูุถูŠู‡ุง ู‡ูˆ ุงู„ู€ object.

ุนุดุงู† ู†ุนู…ู„ ูƒุฏู‡ุŒ ุจู†ุทุจู‚ Dispose method ู…ู† ุงู„ู€ IDisposable interface. ุงู„ู€ class ุจุชุงุนู†ุง ุจูŠูˆุฑุซ ู…ู† ุงู„ู€ interface ุฏู‡ ูˆุจู†ูˆูุฑ ุชู†ููŠุฐ ู„ู„ู€ Dispose method.

ู„ู…ุง ุจุชุนู…ู„ Implement Interface with Dispose PatternุŒ ู‡ุชู„ุงู‚ูŠ ุงู„ูƒูˆุฏ ุฏู‡ ุงุชุนู…ู„ูƒ:

using System;
public class UnmanagedResource : IDisposable
{
    #region IDisposable Support
    private bool disposedValue = false; // To detect redundant calls
    protected virtual void Dispose(bool disposing)
    {
        if (!disposedValue)
        {
            if (disposing)
            {
                // TODO: dispose managed state (managed objects).
            }
            // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
            // TODO: set large fields to null.
            disposedValue = true;
        }
    }
    // ~UnmanagedResource() {
    //   Dispose(false);
    // }
    public void Dispose()
    {
        Dispose(true);
        // GC.SuppressFinalize(this);
    }
    #endregion
}

Understanding Dispose Pattern in C#

  • ุงู„ู€ disposedValue: ู‡ูˆ variable ุนุดุงู† ู†ูƒุชุดู ุงู„ุงุณุชุฏุนุงุกุงุช ุงู„ู…ุชูƒุฑุฑุฉ.
  • ุงู„ู€ Dispose(bool disposing): ู‡ู†ุง ุจู†ูƒุชุจ ุงู„ู€ logic ุงู„ูุนู„ูŠ ุนุดุงู† ู†ุนู…ู„ Destroy ุงู„ู…ูˆุงุฑุฏ ุงู„ู€ managed ูˆุงู„ู€ unmanaged.
  • ุงู„ู€ ~UnmanagedResource() (ุงู„ู€ Finalizer): ุฏู‡ ุจูŠูƒูˆู† ูƒูˆุฏ ุงุญุชูŠุงุทูŠ. ู„ูˆ ุนุงูŠุฒ ุช Destroy ุงู„ู…ูˆุงุฑุฏ ู…ู† ุฎู„ุงู„ู‡ุŒ ุจุชุดูŠู„ ุงู„ูƒูˆู…ู†ุช ูˆุชุณุชุฏุนูŠ Dispose(false).
  • ุงู„ู€ Dispose(): ุฏูŠ ุงู„ู€ method ุงู„ู„ูŠ ุจู†ุณุชุฏุนูŠู‡ุง ู…ู† ุงู„ูƒูˆุฏ ุจุชุงุนู†ุง ุนุดุงู† ู†ู†ุถู Resources. ุจุชุนู…ู„ Call ู„ู€ Dispose(true)ุŒ ูˆู„ูˆ ููŠู‡ finalizerุŒ ุจุชุนู…ู„ Call ู„ู€ GC.SuppressFinalize(this) ุนุดุงู† ุชู‚ูˆู„ ู„ู„ู€ GC ูŠุชุฌุงู‡ู„ ุงู„ู€ destructor.

ุงู„ู€ dispose pattern ุฏู‡ ุจูŠุญุณู† ุฃุฏุงุก ุงู„ุชุทุจูŠู‚ ุจุดูƒู„ ูƒุจูŠุฑ. ูˆุญุชู‰ ู…ุน ุงู„ุชุญูƒู… ุงู„ุตุฑูŠุญ ุฏู‡ุŒ ุงู„ู€ finalizer ุจูŠุจู‚ู‰ ูƒุถู…ุงู† ู„ุชู†ุธูŠู ุงู„ู…ูˆุงุฑุฏ ู„ูˆ ุญุตู„ ูˆูุดู„ ุงุณุชุฏุนุงุก ุงู„ู€ Dispose method.

ุฎู„ูŠู†ุง ู†ุดูˆู ุงู„ู†ุงุชุฌ.

using System;
namespace DestructorDemo
{
    public class UnmanagedResource : IDisposable
    {
        #region IDisposable Support
        private bool disposedValue = false;
        protected virtual void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing)
                {
                    Console.WriteLine("Managed Resources Destroyed by Dispose Method");
                }
                Console.WriteLine("Unmanaged Resources Destroyed by Dispose Method");
                disposedValue = true;
            }
            else
            {
                Console.WriteLine("Resources are Already Destroyed by Dispose Method");
            }
        }
        ~UnmanagedResource()
        {
            Console.WriteLine("Request Comes to Destructor to Destroy the Resources");
            Dispose(false);
        }
        public void Dispose()
        {
            Console.WriteLine("Request Comes to Dispose Method to Destroy the Resources");
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        #endregion
    }
    class Program
    {
        static void Main()
        {
            UnmanagedResource resource = null;
            try
            {
                resource = new UnmanagedResource();
                Console.WriteLine("Using Resources");
            }
            finally
            {
                if (resource != null)
                {
                    Console.WriteLine("Calling Dispose Method to Destroy Resources");
                    resource.Dispose();
                }
            }
            Console.WriteLine("\nTrying to Call the Dispose Method Again To Destroy Resources");
            resource.Dispose();
            Console.ReadKey();
        }
    }
}

Output:

Using Resources
Calling Dispose Method to Destroy Resources
Request Comes to Dispose Method to Destroy the Resources
Managed Resources Destroyed by Dispose Method
Unmanaged Resources Destroyed by Dispose Method

Trying to Call the Dispose Method Again To Destroy Resources
Resources are Already Destroyed by Dispose Method