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 כולן מממשות את הממשק הזה, וכך ניהול משאבים תקין נעשה פשוט ואמין.
אתגר
קלבואו נבנה סימולטור לחיבור למסד נתונים שמדגים ניהול תקין של משאבים באמצעות הממשק 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 יסתיים
}
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1יסודות התכנות מונחה העצמים
קבצים חיצונייםמרחבי שמות והנחיותמבוא למחלקות ולאובייקטיםמילת המפתח 'this'מתודות ופרמטריםשדות לעומת מאפייניםבנאיםאתחול אובייקטיםסיכום – מחשבון פשוט4ירושה
תחביר ירושה בסיסית (:)מילת המפתח 'base'מילות המפתח Virtual ו-Overrideמחלקות Sealedמחלקת הבסיס 'object'סיכום – היררכיית עובדים7תכונות מתקדמות
העמסת אופרטוריםאינדקסרים (this[])דריסת ToString()מתודות הרחבהסיכום – רשימה מותאמת אישית2מאפיינים וחברים סטטיים
מאפיינים במימוש אוטומטימאפיינים לקריאה בלבד ולכתיבה בלבדשדות ומתודות סטטייםמחלקות סטטיותחברים עם גוף ביטוי5פולימורפיזם וממשקים
פולימורפיזם בזמן קומפילציה לעומת בזמן ריצהממשק לעומת מחלקה מופשטתממשקים מרוביםממשקים מפורשיםהמרה כלפי מעלה והמרה כלפי מטהחזרה: מחשבון צורות8מושגים מתקדמים בתכנות מונחה עצמים
קומפוזיציה במקום ירושהGenerics (מחלקות ומתודות)נציגים ואירועיםמאפיינים ורפלקציהIDisposable והצהרת usingיסודות הזרקת תלויותתרגלו בעצמכם: קומפיילר C# אונליין