واجهة 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 هذه الواجهة، مما يجعل الإدارة السليمة للموارد مباشرة وموثوقة.
التحدي
سهللنبنِ محاكي اتصال بقاعدة بيانات يوضّح الإدارة السليمة للموارد باستخدام واجهة IDisposable وعبارة using. ستنشئ class يتتبّع أوقات فتح الاتصالات وإغلاقها، مما يضمن تحرير الموارد دائمًا بطريقة صحيحة.
ستنظّم التعليمات البرمجية عبر ملفين:
DatabaseConnection.cs: أنشئ class باسمDatabaseConnectionفي namespaceDataAccess، بحيث 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}
- امتلاك property باسم
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
}
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1أساسيات OOP
الملفات الخارجيةNamespaces والتوجيهاتمقدمة في Classes و Objectsالكلمة المفتاحية 'this'Methods والمعاملاتFields مقابل PropertiesConstructorsObject Initializersمراجعة - آلة حاسبة بسيطة4الوراثة
صيغة الوراثة الأساسية (:)الكلمة المفتاحية 'base'الكلمات المفتاحية Virtual و Overrideالأصناف المختومة (Sealed Classes)الفئة الأساسية 'object'مراجعة - هيكلية الموظفين7ميزات متقدمة
تحميل العوامل (Operator Overloading)المفهرسات (Indexers (this[]))إعادة تعريف ()ToStringدوال التوسعة (Extension Methods)ملخص - Custom List2الخصائص والأعضاء الساكنة (Static Members)
الخصائص المطبقة تلقائيًا (Auto-Implemented Properties)خصائص القراءة فقط والكتابة فقطالحقول والدوال الساكنة (Static)الفئات الساكنة (Static Classes)الأعضاء ذات البنية التعبيرية (Expression-Bodied Members)5تعدد الأشكال والواجهات (Polymorphism & Interfaces)
تعدد الأشكال: وقت التجميع مقابل وقت التشغيلالواجهة مقابل الفئة المجردة (Abstract Class)الواجهات المتعددةالواجهات الصريحةUpcasting و Downcastingملخص - حاسبة الأشكال8مفاهيم البرمجة كائنية التوجه (OOP) المتقدمة
التركيب بدلاً من الوراثةالـ Generics (الأصناف والدوال)الـ Delegates والأحداثالـ Attributes والـ Reflectionواجهة IDisposable وجملة usingأساسيات Dependency Injectionتدرّب بنفسك: مترجم C# عبر الإنترنت