Menu
Coddy logo textTech

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() כשהמתודה מסתיימת

ההצהרה using פועלת עם כל סוג שמממש את IDisposable. מחלקות מובנות כמו StreamReader, SqlConnection ו־HttpClient כולן מממשות את הממשק הזה, וכך ניהול משאבים תקין נעשה פשוט ואמין.

challenge icon

אתגר

קל

בואו נבנה סימולטור לחיבור למסד נתונים שמדגים ניהול תקין של משאבים באמצעות הממשק IDisposable וההצהרה using. תיצרו מחלקה שעוקבת אחר פתיחת חיבורים וסגירתם, ומבטיחה שהמשאבים ישוחררו תמיד כראוי.

תארגנו את הקוד בשני קבצים:

  • DatabaseConnection.cs: צרו מחלקה בשם DatabaseConnection במרחב השמות DataAccess, שמממשת את IDisposable. החיבור שלכם צריך:
    • להכיל מאפיין ConnectionName (מחרוזת, לקריאה בלבד) שמוגדר באמצעות הבנאי
    • לעקוב אחר השאלה אם החיבור שוחרר, באמצעות שדה בוליאני פרטי
    • להדפיס Connection opened: {ConnectionName} בעת יצירת האובייקט (בבנאי)
    • לממש את המתודה Dispose() כדי להדפיס Connection closed: {ConnectionName} — אבל רק אם החיבור עדיין לא שוחרר (כדי למנוע שחרור כפול)
    • להכיל מתודה Query(string sql) שמחזירה Executing on {ConnectionName}: {sql}
  • Program.cs: בקובץ הראשי שלכם, הדגימו ניהול תקין של משאבים באמצעות ההצהרה using עם החיבור למסד הנתונים. צרו חיבור, בצעו שאילתה, ותנו לבלוק using לטפל בניקוי באופן אוטומטי.

תקבלו שני קלטים:

  • שם החיבור (למשל, MainDB)
  • שאילתת SQL לביצוע (למשל, SELECT * FROM Users)

השתמשו בהצהרת using כדי ליצור את החיבור. בתוך הבלוק, קראו למתודה Query והדפיסו את התוצאה שלה. כשהבלוק using מסתיים, המתודה Dispose() תיקרא באופן אוטומטי.

לדוגמה, אם הקלטים הם MainDB ו-SELECT * FROM Users, הפלט צריך להיות:

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

שימו לב שהחיבור נסגר אוטומטית כשהבלוק using מסתיים — לעולם לא תצטרכו לזכור לקרוא ידנית למתודה Dispose(). התבנית הזאת מבטיחה שהמשאבים ינוקו תמיד, גם אם מתרחשת חריגה בתוך הבלוק!

נסו בעצמכם

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# אונליין