نابودکننده در سی شارپ «#Destructors in C» یکی از ویژگیهای مهم و کلیدی برای مدیریت منابع به شمار میرود. در این مقاله، با ساختار و ویژگیهای نابودکننده در سی شارپ آشنا شده و نحوه استفاده صحیح از آنها را در پروژههای برنامهنویسی بررسی خواهیم کرد. همچنین اهمیت نابودکننده در مدیریت حافظه و آزادسازی منابعی مانند فایلها و اتصالات پایگاه داده را مورد بحث قرار میدهیم.
نابودکننده در سی شارپ
نابودکننده در سی شارپ متدهایی در داخل کلاس هستند که برای از بین بردن نمونههای آن کلاس زمانی که دیگر نیازی به آنها نیست، استفاده میشوند. نابودکننده به صورت ضمنی توسط جمعکننده زباله (Garbage Collector) چارچوب .NET فراخوانی میشود و برنامهنویس کنترلی بر زمان فراخوانی آن ندارد. یک متغیر نمونه یا شیء زمانی برای نابودی واجد شرایط میشود که دیگر قابل دسترسی نباشد.
ویژگیهای نابودکننده در سی شارپ
- نابودکننده برای هر کلاس منحصربهفرد است، یعنی نمیتوان بیش از یک نابودکننده در یک کلاس داشت.
- نابودکننده نوع بازگشتی ندارد و دقیقاً همان نام کلاس را دارد (شامل حساسیت به حروف کوچک و بزرگ).
- نابودکننده با استفاده از علامت (~) قبل از نام خود از سازنده متمایز میشود.
- نابودکننده هیچ پارامتر یا اصلاحکنندهای نمیپذیرد.
- نابودکننده نمیتواند در ساختارها تعریف شود و فقط برای کلاسها استفاده میشود.
- نابودکننده قابل بارگذاری مجدد «Overload» یا ارثبری «Inheritance» نیست.
- نابودکننده زمانی که برنامه خاتمه مییابد، فراخوانی میشود.
- به طور داخلی، نابودکننده متد Finalize را روی کلاس پایه شیء فراخوانی میکند.
ساختار نابودکننده در سی شارپ
یک نابودکننده با نماد تیلد (~) که پیشوند نام آن است، از سازنده «Constructor» متمایز میشود. نابودکننده در سی شارپ هیچ پارامتری دریافت نمیکند و هیچ مقداری، حتی نوع void، باز نمیگرداند. مشابه سازنده، نابودکننده نیز برای کلاس منحصربهفرد است، به این معنا که هر کلاس میتواند فقط یک نابودکننده داشته باشد.
class Example { // Rest of the class constructor , // members and methods. // Destructor ~Example() { // Your code } }
مثال: تکه کد زیر نمونهای ساده از استفاده از سازنده «Constructor» و ویرانگر «Destructor» در زبان برنامهنویسی #C است.
// How to use Destructor using System; class PStore { // Constructor public PStore() { Console.WriteLine("Object Created."); } // Destructor ~PStore() { Console.WriteLine("Object Destroyed."); } public void DisplayMessage() { Console.WriteLine("Message Printed."); } public static void Main(string[] args) { // Create an instance of PStore PStore p = new PStore(); // Destructor will be called when // p goes out of scope p.DisplayMessage(); } }
خروجی
Object Created. Message Printed. Object Destroyed.
توضیح: سازنده (Constructor) زمانی فراخوانی میشود که یک شیء جدید ایجاد میگردد و پس از آن تمام عملیات روی شیء انجام میشوند. در انتها، قبل از خروج از متد Main، تمام عناصر شیء نابود میشوند.
اجرای ویرانگر به Garbage Collector وابسته است، بنابراین ممکن است فوراً پس از پایان برنامه یا در زمان دیگری اجرا شود.
مواردی که باید قبل از استفاده از نابودکنندهها بدانید
در برنامهنویسی شیءگرا، نابودکنندهها (Destructors) بهطور خودکار برای آزادسازی منابعی که توسط یک شیء استفاده میشود، فراخوانی میشوند. اما قبل از استفاده از آنها، باید برخی نکات کلیدی را در نظر داشته باشید:
۱- نابودکنندهها فقط در کلاسها تعریف میشوند، نه در ساختارها (Structures)
نابودکنندهها مخصوص کلاسها هستند و نمیتوانند در ساختارها (Structures) استفاده شوند. ساختارها در سیشارپ نوعی داده هستند که بهطور خودکار حافظه را مدیریت میکنند و به همین دلیل نیازی به نابودکنندهها ندارند.
۲- نابودکنندهها نمیتوانند بارگذاری مجدد (Overload) شوند یا به ارث برده شوند
در سیشارپ، نابودکنندهها ویژگیهای خاص خود را دارند:
- بارگذاری مجدد: نابودکنندهها نمیتوانند بیش از یک نسخه داشته باشند. فقط یک نابودکننده در کلاس میتواند وجود داشته باشد.
- وراثت: نابودکنندهها قابل ارثبری نیستند، یعنی نمیتوان آنها را در کلاسهای فرزند بازنویسی (override) کرد.
۳- نابودکنندهها زمانی فراخوانی میشوند که برنامه خاتمه یابد
نابودکنندهها بهطور خودکار زمانی فراخوانی میشوند که شیء از حافظه حذف میشود و برنامه در حال خاتمه است. این معمولاً زمانی اتفاق میافتد که شیء دیگر در دسترس نباشد و جمعآوری زباله (Garbage Collection) در سیشارپ آن را شناسایی و حذف کند.
۴- نابودکننده متد Finalize را روی کلاس پایه شیء فراخوانی میکند
در واقع نابودکنندهها بهطور داخلی متد Finalize را روی کلاس پایه شیء (که معمولاً کلاس Object است) فراخوانی میکنند. متد Finalize وظیفه آزادسازی منابع غیرمدیریتی مانند فایلها یا ارتباطات شبکه را دارد.
مثال: قطعه کد زیر مثالی دیگر برای استفاده از سازنده «Constructor» و ویرانگر «Destructor» است که با یک کلاس به نام Complex، کار با مقادیر عددی مختلط را نشان میدهد.
// Demonstration of Destructor using System; class Complex { private int real, img; // Constructor public Complex() { real = 0; img = 0; } // Method to set values public void SetValue(int r, int i) { real = r; img = i; } // Method to display values public void DisplayValue() { Console.WriteLine($"Real = {real}, Imaginary = {img}"); } // Destructor ~Complex() { Console.WriteLine("Object Destroyed"); } } class PStore { static void Main(string[] args) { // Create instance Complex c = new Complex(); c.SetValue(2, 3); c.DisplayValue(); // Destructor will be called automatically // when 'c' goes out of scope. } }
خروجی
Real = 2, Imaginary = 3 Object Destroyed
توضیح: در مثال بالا، کلاس شامل یک سازنده ()Complex، یک متد SetValue برای مقداردهی به نمونه کلاس Complex، یک متد DisplayValue برای نمایش مقدار نمونه، و یک نابودکننده ()Complex~ برای از بین بردن شیء زمانی که دیگر نیازی به آن نیست، میباشد. نابودکننده پیامی با مضمون “Destructor was called” چاپ میکند، که برنامهنویس میتواند پیام دلخواه خود را تعیین کند یا آن را خالی بگذارد.
نابودکننده عمدتاً برای آزادسازی منابعی مانند حافظه، دستههای فایل «file handles»، یا اتصالات پایگاه داده استفاده میشود تا اطمینان حاصل شود که هیچ منبعی هنگام خروج شیء از حوزه «scope» معلق باقی نمیماند.
جمع بندی
در این مقاله، با مفهوم نابودکننده در سی شارپ و نقش آنها در مدیریت منابع آشنا شدیم. نابودکننده به طور خودکار توسط جمعکننده زباله «Garbage Collector» فراخوانی میشوند و وظیفه آزادسازی منابعی مانند حافظه، فایلها و اتصالات پایگاه داده را بر عهده دارند. این ویژگی باعث میشود برنامهها بهینهتر عمل کرده و از هدررفت منابع جلوگیری شود. همچنین، محدودیتهای نابودکنندهها مانند عدم امکان تعریف در ساختارها، بارگذاری مجدد «Overloading» و ارثبری «Inheritance»، و نحوه عملکرد آنها در مقایسه با سازندهها را بررسی کردیم.
به طور کلی، نابودکنندهها ابزاری قدرتمند برای مدیریت منابع هستند که استفاده صحیح و بهینه از آنها میتواند نقش مهمی در پایداری و کارایی برنامههای #C داشته باشد. برنامهنویسان باید با درک کامل از عملکرد و محدودیتهای نابودکنندهها، آنها را به درستی در پروژههای خود به کار بگیرند تا از مشکلاتی مانند نشت حافظه و منابع بلااستفاده جلوگیری کنند.
مقاله شما عالی بود، ولی بهتر است مقایسهای بین سازنده و نابودکننده در قالب یک جدول اضافه کنید تا تفاوتهای آنها واضحتر باشد.
مقاله شما عالی بود. تشکر از توضیحات خوب شما.
مقاله شما عالی بود، ولی بهتر است مقایسهای بین سازنده و نابودکننده در قالب یک جدول اضافه کنید تا تفاوتهای آنها واضحتر باشد.
خیلی خوب بود. توضیحات شما در مورد نحوه عملکرد نابودکننده ها کاملا روشن بود.
سپاسگزارم