# מערך שיעור: Nullable Types📋 מערך מרצה

משך: 1.5 שעות אקדמיות (68 דקות).

מטרת השיעור: הסטודנטים יבינו למה טיפוס Value לא יכול באופן טבעי להיות "ריק", ואיך `int?`/`??`/`?.` פותרים את זה.

בסוף השיעור הסטודנטים צריכים: להצהיר ולבדוק משתנה Nullable, להשתמש ב-`??` לערך ברירת מחדל, ולהסביר למה מוסכמות כמו `-1`/`0` ל"אין ערך" מסוכנות.

דגש קריטי: פתחו עם דוגמה קונקרטית של מוסכמת מספר-קסם ל"ריק" (`age = -1`) שמשבשת חישוב אמיתי — זו הבעיה שמצדיקה את כל השיעור.

---

## מהלך השיעור

| חלק בשיעור | משך | הערות ודגשים |
| --- | --- | --- |
| פתיחה וחיבור | 5 דקות | שאלו: "איך הייתם מסמנים 'גיל לא ידוע' במשתנה int?" |
| הבעיה: מוסכמת מספר-קסם | 10 דקות | הראו למה `-1`/`0` בעייתי — מתנגש עם ערכים תקינים |
| הרעיון: int? | 15 דקות | הצגה, HasValue/Value |
| קוד: ?? ו-?. | 20 דקות | שתי הדוגמאות, קישרו ל-NullReferenceException |
| תרגול מודרך | 15 דקות | תרגיל 1+2 |
| שאלות + סיכום | 3 דקות | חיזרו על "אין ערך זה מצב נבדק, לא מספר מוסכם" |

---

## דגשים להעברת השיעור

- זהו שיעור-הכנה חשוב לפרק Exceptions הבא — הזכירו במפורש בסוף שקריאה ל-`.Value` על `null` היא בדיוק סוג התקלה שנלמד לתפוס בעדינות בשיעור הבא, לא רק "עוד תחביר".
- אל תציגו `?.`/`??` לפני שהראיתם `HasValue`/`Value` המפורשים — חשוב שסטודנטים יבינו קודם *מה* קורה מתחת למכסה, לפני קיצור הדרך.

---

## מושגים

**`int?` / `Nullable<T>`** — טיפוס Value שיכול גם להכיל `null`.
**`.HasValue`** — בדיקה אם יש ערך אמיתי.
**`.Value`** — שליפת הערך בפועל; זורק חריגה אם `null`.
**`??`** — Null-Coalescing — ערך ברירת מחדל אם `null`.
**`?.`** — Null-Conditional — גישה בטוחה שמונעת `NullReferenceException`.

---

## תרגיל חשיבה

**שאלת פתיחה:** "אם משתמשים ב-`-1` כדי לסמן 'משכורת לא ידועה' בשדה `int`, ואז מישהו מחשב ממוצע משכורות על כל העובדים — מה קורה?"

**מהלך:** תנו לסטודנטים לחשב בעצמם — הממוצע יורד באופן שגוי כי `-1` נכנס לחישוב כאילו הוא ערך אמיתי. הובילו לתובנה: מספר-קסם ל"ריק" לא רק מכוער — הוא מייצר באגים חישוביים אמיתיים ושקטים.

**מה המרצה מראה בסוף:** כתבו קוד עם רשימת משכורות שכוללת `-1` "כמוסכמה", וחשבו ממוצע — התוצאה מוטה ושגויה. אחר כך אותו תרחיש עם `double?` ו-`null` אמיתי, עם סינון מפורש (`Where(s => s.HasValue)`) לפני החישוב — התוצאה נכונה כי ה"ריק" לא נכנס בטעות לחישוב.
