# משתנים וטיפוסים📖 שיעור

## מה זה?

בשפות דינמיות (כמו JavaScript או Python) אפשר לכתוב `x = 5` ואז `x = "hello"` באותו משתנה בלי שאף אחד יתלונן — עד שבמקום לא צפוי בזמן ריצה, הקוד מנסה לחבר מספר למחרוזת ומתרסק. C# פותרת את זה עם **Strong Static Typing**: לכל משתנה יש טיפוס קבוע שנקבע בזמן קומפילציה, וניסיון להכניס אליו ערך מהטיפוס הלא נכון נתפס **לפני** שהתוכנית בכלל רצה — לא בפרודקשן, אצל משתמש אמיתי.

## מילות מפתח שחשוב לזכור

• Literal — ערך קבוע כתוב ישירות בקוד (`5`, `"שלום"`, `true`)

• Static Typing — טיפוס המשתנה נקבע ונבדק בזמן קומפילציה, לא בזמן ריצה

• `var` — הצהרה עם טיפוס משתמע; C# עדיין קובעת את הטיפוס בקומפילציה לפי הערך הראשוני — זה **לא** דינמי

• Primitive Types — טיפוסים בסיסיים כמו `int`, `double`, `bool`, `char`, שמייצגים ערך יחיד ישירות

• Reference/Object Types — טיפוסים כמו `string` או מחלקות מותאמות-אישית, שמחזיקים הפניה לאובייקט

```csharp
int age = 25;              // primitive — whole number
double price = 19.99;      // primitive — decimal number
bool isActive = true;      // primitive — true/false
char grade = 'A';          // primitive — single character
string name = "Dana";      // reference type — object

var score = 100;           // C# infers: score is int, and stays int forever
// score = "high";         // compilation error — CS0029: cannot convert string to int
```

```mermaid
flowchart TD
    A["int age = 25;"] --> B{"Trying: age = 'text';"}
    B -->|"C# — Static Typing"| C["Compilation error<br/>immediately, before running"]
```

## הסבר עיקרי

`var` הוא לא "טיפוס דינמי" — `var` רק אומר לקומפיילר "תסיק את הטיפוס בעצמך לפי הערך הראשוני". ברגע שהוא הוסק (`var score = 100;` → `score` הוא `int`), הוא **קבוע** לכל אורך חיי המשתנה, בדיוק כמו לוּ נכתב `int score = 100;` במפורש. זה שונה לגמרי מ-JavaScript, שם `let x` יכול להחזיק כל טיפוס בכל רגע.

Primitive מול Object — טיפוסים פרימיטיביים (`int`, `double`, `bool`, `char`) מחזיקים את הערך עצמו ישירות; טיפוסי Object/Reference (`string`, מחלקות) מחזיקים הפניה (reference) לאובייקט שמאוחסן בנפרד. ההבדל הזה יהיה קריטי בהמשך כשנדבר על Value מול Reference בהעברת פרמטרים לפונקציות — כאן מספיק לזכור שהם מתנהגים אחרת.

זמן קומפילציה מול זמן ריצה — הבדיקה של C# קורית **כשמריצים `dotnet build`**, לא כשהתוכנית באמת רצה אצל משתמש. זו הסיבה שבפיתוח ב-C# מגלים שגיאות טיפוסים מוקדם בהרבה — לפני שהקוד בכלל הגיע לבדיקה, ובטח לפני production.

## יתרונות

שגיאות טיפוסים נתפסות בזמן קומפילציה, לפני שהקוד רץ בכלל — לא כ"הפתעה" בפרודקשן; IDE יודע להציע Autocomplete מדויק כי הוא יודע בוודאות מה הטיפוס של כל משתנה; קוד עם טיפוסים מפורשים קריא יותר — רואים מיד מה כל משתנה אמור להכיל.

## חסרונות

צריך להצהיר על טיפוסים (או לפחות לתת לקומפיילר להסיק אותם) — יותר "טקסט" מקוד בשפה דינמית; לפעמים הטיפוס הנכון לא ברור מראש וצריך refactor אם משנים כיוון (למשל שדה שהיה `int` וצריך שיהיה `double`).

## נקודות חשובות

• Static Typing = טיפוסים נבדקים בזמן קומפילציה; Dynamic Typing = נבדקים בזמן ריצה

• `var` לא הופך את C# לדינמית — הטיפוס עדיין נקבע בקומפילציה, רק מוסק אוטומטית

• טיפוסים פרימיטיביים מחזיקים ערך ישירות; טיפוסי Object/Reference מחזיקים הפניה

• `string` הוא reference type, למרות שמתנהג בהרבה מקומות "כמו" ערך פשוט

## טעויות נפוצות

• לחשוב ש-`var` הופך משתנה לגמיש כמו ב-JavaScript — הוא לא, הטיפוס קבוע מרגע ההסקה

• לנסות להשוות `int` ל-`string` ישירות ולהתפלא משגיאת קומפילציה

• לבלבל בין הצהרת טיפוס (`int age;`) לאתחול ערך (`age = 25;`) — אפשר להצהיר בלי לאתחל, אבל לא להשתמש בערך לפני שהוא מאותחל

## סיכום

C# היא שפה עם Strong Static Typing — כל משתנה מקבל טיפוס קבוע שנבדק כבר בזמן קומפילציה, מה שתופס שגיאות סוג לפני שהתוכנית בכלל רצה. `var` הוא נוחות תחבירית להסקת טיפוס, לא מעבר לטיפוסיות דינמית. ההבחנה בין טיפוסים פרימיטיביים (ערך ישיר) לטיפוסי Object/Reference (הפניה לאובייקט) היא יסוד שיחזור וישפיע על נושאים מתקדמים יותר בהמשך.

## דוקומנטציה רשמית

[Microsoft Learn — Built-in types](https://learn.microsoft.com/dotnet/csharp/language-reference/builtin-types/built-in-types)

[Microsoft Learn — var keyword](https://learn.microsoft.com/dotnet/csharp/language-reference/statements/declarations#implicitly-typed-local-variables)

---

## תרגילים

### תרגיל 1 — טיפוסים בסיסיים

**המשימה:** הצהירו על 5 משתנים: `int`, `double`, `bool`, `char`, `string`, כל אחד עם ערך מתאים, והדפיסו את כולם עם `Console.WriteLine`.

**בדיקה:** התוכנית מתקמפלת ומדפיסה 5 שורות, כל אחת עם הערך והטיפוס הנכונים.

### תרגיל 2 — שגיאת קומפילציה מכוונת

**המשימה:** כתבו `int number = 10;` ואז נסו להריץ `number = "text";`. תעדו את הודעת השגיאה שהקומפיילר מציג.

**בדיקה:** הקוד לא מתקמפל; הודעת השגיאה מזכירה שלא ניתן להמיר `string` ל-`int` (CS0029).

---

## פרויקט מסכם

**המשימה:** כתבו תוכנית "כרטיס ביקור" שמאחסנת פרטי אדם ומדפיסה אותם בפורמט קריא.

**דרישות:**
1. משתנים: `name` (`string`), `age` (`int`), `heightMeters` (`double`), `isStudent` (`bool`)
2. לפחות משתנה אחד מוצהר עם `var` (עם הסקת טיפוס)
3. הדפסה של כל הפרטים במשפט אחד מלא, לדוגמה: `"דנה, בת 25, גובה 1.7 מ', סטודנטית: כן"`

**בדיקה:** התוכנית מתקמפלת ללא שגיאות, ומדפיסה את כל הפרטים בפורמט קריא ומדויק.

## מה בפרק הבא

בפרק הבא — **קלט/פלט בסיסי**: איך מקבלים מהמשתמש קלט עם `Console.ReadLine`, ולמה תמיד צריך להמיר אותו במפורש מ-`string` לטיפוס הרצוי.
