Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

واجهة IDisposable وجملة using

جزء من قسم البرمجة كائنية التوجه في رحلة C# على Coddy. الدرس 45 من 70.

تحتفظ بعض الكائنات بالموارد التي لا يستطيع جامع القمامة تنظيفها تلقائيًا - مقابض الملفات، واتصالات قواعد البيانات، ومقابس الشبكة. توفّر واجهة IDisposable طريقةً قياسية لتحرير هذه الموارد عند الانتهاء من استخدامها.

يطبّق الصنف IDisposable من خلال توفير أسلوب Dispose():

public class FileHandler : IDisposable
{
    private bool disposed = false;
    
    public void Dispose()
    {
        if (!disposed)
        {
            Console.WriteLine("Releasing resources...");
            disposed = true;
        }
    }
}

يمكنك استدعاء Dispose() يدويًا، لكن ماذا لو حدث استثناء قبل أن تصل إلى ذلك السطر؟ تضمن عبارة using تنفيذ عملية التنظيف، حتى عندما تسوء الأمور:

using (FileHandler handler = new FileHandler())
{
    // اعمل مع الـ handler
}  // يتم استدعاء Dispose() تلقائيًا هنا

توفّر C# الحديثة صياغة أنظف باستخدام تصريح using، الذي يتخلّص من الكائن عند خروجه من النطاق:

void ProcessFile()
{
    using FileHandler handler = new FileHandler();
    // العمل مع handler
}  // يُستدعى Dispose() عند خروج الـ method

تعمل عبارة using مع أي نوع ينفّذ IDisposable. تنفّذ الفئات المضمّنة مثل StreamReader وSqlConnection وHttpClient هذه الواجهة، مما يجعل الإدارة السليمة للموارد مباشرة وموثوقة.

challenge icon

التحدي

سهل

لنبنِ محاكي اتصال بقاعدة بيانات يوضّح الإدارة السليمة للموارد باستخدام واجهة IDisposable وعبارة using. ستنشئ class يتتبّع أوقات فتح الاتصالات وإغلاقها، مما يضمن تحرير الموارد دائمًا بطريقة صحيحة.

ستنظّم التعليمات البرمجية عبر ملفين:

  • DatabaseConnection.cs: أنشئ class باسم DatabaseConnection في namespace DataAccess، بحيث implements الواجهة IDisposable. يجب أن يقوم اتصالك بما يلي:
    • امتلاك property باسم ConnectionName (من النوع string، للقراءة فقط) يتم تعيينها من خلال constructor
    • تتبّع ما إذا كان الاتصال قد تم التخلص منه باستخدام private boolean field
    • طباعة Connection opened: {ConnectionName} عند إنشاء الكائن (في constructor)
    • Implement الطريقة Dispose() لطباعة Connection closed: {ConnectionName} - ولكن only إذا لم تتم عملية التخلص بالفعل (لمنع التخلص المزدوج)
    • امتلاك الطريقة Query(string sql) التي تُرجع Executing on {ConnectionName}: {sql}
  • Program.cs: في ملفك الرئيسي، اعرض الإدارة السليمة للموارد باستخدام عبارة using مع اتصال قاعدة البيانات. أنشئ اتصالًا، ونفّذ استعلامًا، ودع block الخاص بـ using يتولى التنظيف automatically.

ستتلقى مُدخلين:

  • اسم الاتصال (مثلًا، MainDB)
  • استعلام SQL المطلوب تنفيذه (مثلًا، SELECT * FROM Users)

استخدم عبارة using لإنشاء اتصالك. Inside الـ block، استدعِ الطريقة Query واطبع نتيجتها. عند انتهاء block الخاص بـ using، سيتم استدعاء Dispose() تلقائيًا.

على سبيل المثال، إذا كانت المُدخلات هي MainDB وSELECT * FROM Users، فيجب أن يكون الناتج:

Connection opened: MainDB
Executing on MainDB: SELECT * FROM Users
Connection closed: MainDB

لاحظ كيف يُغلق الاتصال automatically عند انتهاء block الخاص بـ using - فلن تضطر أبدًا إلى تذكّر استدعاء Dispose() يدويًا. يضمن هذا النمط تنظيف الموارد دائمًا، حتى إذا حدث استثناء داخل block!

جرّب بنفسك

using System;
using DataAccess;

class Program
{
    public static void Main(string[] args)
    {
        string connectionName = Console.ReadLine();
        string sqlQuery = Console.ReadLine();
        
        // TODO: استخدم عبارة 'using' لإنشاء DatabaseConnection
        // داخل كتلة using:
        // 1. استدعِ الطريقة Query مع sqlQuery
        // 2. اطبع نتيجة الطريقة Query
        // سيتم استدعاء الطريقة Dispose تلقائيًا عند انتهاء كتلة using
        
    }
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم C# عبر الإنترنت