Menu
Coddy logo textTech

נציגים ואירועים

חלק מהיחידה תכנות מונחה עצמים במסלול ה-C# של Coddy. שיעור 43 מתוך 70.

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

מכריזים על נציג באמצעות ציון חתימת המתודה שאליה הוא יכול להפנות:

public delegate void Notify(string message);

public class Publisher
{
    public void SendAlert(string msg) => Console.WriteLine("Alert: " + msg);
}

// שימוש
Notify notifier = new Publisher().SendAlert;
notifier("System started");  // Alert: System started

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

public class Button
{
    public event Action Clicked;
    
    public void Click()
    {
        Clicked?.Invoke();  // הודע לכל המנויים
    }
}

// הרשמה לאירוע
Button btn = new Button();
btn.Clicked += () => Console.WriteLine("Button was clicked!");
btn.Click();  // בוצעה לחיצה על הכפתור!

האופרטור += רושם מטפל, ואילו -= מבטל את הרישום שלו. התבנית ?.Invoke() קוראת לאירוע בבטחה רק אם יש לו מנויים. אירועים הם יסודיים ביישומי GUI, במנועי משחקים ובכל מערכת שבה אובייקטים צריכים להגיב לשינויים ללא צימוד הדוק.

challenge icon

אתגר

קל

בואו נבנה מערכת לניטור טמפרטורה שמשתמשת בנציגים ובאירועים כדי להודיע למנויים בכל פעם שהטמפרטורה משתנה. זוהי דוגמה קלאסית לדפוס פרסום-מינוי שאירועים מאפשרים בצורה אלגנטית כל כך.

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

  • TemperatureMonitor.cs: צרו מחלקה בשם TemperatureMonitor במרחב השמות Monitoring, שתשמש כמפרסם. המנטר שלכם צריך:
    • להכיל שדה פרטי לאחסון הטמפרטורה הנוכחית
    • להצהיר על אירוע באמצעות Action<int> בשם TemperatureChanged, שמופעל בכל פעם שהטמפרטורה מתעדכנת
    • להכיל מאפיין Temperature מסוג int, שבו הקובע מעדכן את השדה הפרטי ומפעיל את האירוע עם ערך הטמפרטורה החדש
    זכרו להשתמש בתבנית ?.Invoke() כדי להפעיל את האירוע בבטחה רק כשיש מנויים.
  • Program.cs: בקובץ הראשי שלכם, צרו מופע של TemperatureMonitor ורשמו שני מטפלים שונים לאירוע TemperatureChanged שלו:
    • מטפל אחד שמדפיס: Alert: Temperature is now {value} degrees
    • מטפל נוסף שמדפיס: Logged: {value}
    לאחר רישום שני המטפלים, הגדירו את הטמפרטורה פעמיים באמצעות ערכים מהקלט. בכל פעם שתגדירו את הטמפרטורה, שני המטפלים אמורים להגיב.

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

  • ערך הטמפרטורה הראשון (מספר שלם)
  • ערך הטמפרטורה השני (מספר שלם)

לדוגמה, אם הקלטים הם 25 ו-30, הפלט אמור להיות:

Alert: Temperature is now 25 degrees
Logged: 25
Alert: Temperature is now 30 degrees
Logged: 30

שימו לב כיצד הגדרת המאפיין Temperature מודיעה אוטומטית לכל המנויים — המנטר לא צריך לדעת דבר על מי שמאזין. זה היופי בגישה מבוססת האירועים!

נסו בעצמכם

using System;
using Monitoring;

class Program
{
    public static void Main(string[] args)
    {
        // קרא את הקלט
        int temp1 = Convert.ToInt32(Console.ReadLine());
        int temp2 = Convert.ToInt32(Console.ReadLine());

        // TODO: צור מופע של TemperatureMonitor

        // TODO: רשום מטפל שמדפיס: "Alert: Temperature is now {value} degrees"

        // TODO: רשום מטפל נוסף שמדפיס: "Logged: {value}"

        // TODO: הגדר את הטמפרטורה ל-temp1

        // TODO: הגדר את הטמפרטורה ל-temp2
    }
}
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: קומפיילר C# אונליין