מבוא ל-C# ו-.NET
מה זה?
מחשב לא מבין קובץ .cs ישירות — הוא מבין רק הוראות מעבד ברמת ה-0/1. C# פותרת את זה בשני שלבים: קודם קומפיילר (csc) הופך את הקוד למעין “שפת ביניים” בשם IL (Intermediate Language), ואז ה-CLR (Common Language Runtime) — סביבת הריצה של .NET — מריץ את ה-IL בפועל, ומתרגם אותו לקוד מכונה אמיתי תוך כדי ריצה (JIT — Just-In-Time compilation). זה בדיוק ההבדל בין “לכתוב קוד” ל"להריץ קוד".
מילות מפתח שחשוב לזכור
• Compilation — תהליך הפיכת קוד המקור (.cs) לקוד ביניים שאפשר להריץ
• IL (Intermediate Language) — קוד הביניים שהקומפיילר מייצר; לא תלוי במעבד ספציפי
• CLR (Common Language Runtime) — סביבת הריצה של .NET שמריצה IL בפועל, כולל JIT ו-Garbage Collector
• .NET CLI — כלי שורת פקודה (dotnet) ליצירה, הרצה ובנייה של פרויקטים
• Main — מתודת הכניסה של כל תוכנית קונסולה ב-C#; שם ההרצה מתחילה
// Program.cs — entry point of every console program
Console.WriteLine("Hello, C#!");# .NET CLI — create, run and build
dotnet new console -o MyApp # Creates a new console project in the MyApp folder
dotnet run # Compiles and runs in a single command
dotnet build # Only compiles, without running
flowchart RL
A["Program.cs<br/>source code"] -->|"dotnet build<br/>compilation"| B["IL<br/>intermediate code"]
B -->|"dotnet run<br/>CLR + JIT"| C["Machine code<br/>runs in practice"]
הסבר עיקרי
למה יש שני שלבים ולא אחד — קומפילציה ישירה לקוד מכונה הייתה אומרת שכל תוכנית תלויה במעבד/מערכת הפעלה הספציפיים שעליהם קומפילו אותה. IL הוא שכבת-ביניים נייטרלית: אותו IL רץ על Windows, Linux או Mac, כי ה-CLR של כל מערכת יודע לתרגם אותו לקוד מכונה מקומי ברגע ההרצה (JIT). זו הסיבה ש-.NET מתואר כ"cross-platform".
dotnet run מסתיר שני שלבים — כשמריצים dotnet run, בפועל קורים שני דברים ברצף: קודם dotnet build (קומפילציה ל-IL), ואז הפעלת ה-CLR שמריץ את התוצאה. בזמן פיתוח נוח להשתמש ב-dotnet run; כשרוצים רק לוודא שהקוד מתקמפל בלי להריץ (למשל ב-CI), משתמשים ב-dotnet build לבד.
Main הוא תמיד נקודת ההתחלה — בפרויקט קונסולה, ה-CLR תמיד מתחיל להריץ מהמתודה Main (או, בגרסאות מודרניות של C#, מהשורה הראשונה של הקובץ הראשי — “Top-level statements”, כמו בדוגמה למעלה). זה שקול מבחינה תפקודית ל-function main() בשפות אחרות.
יתרונות
הפרדת קומפילציה מהרצה מאפשרת תוכנית אחת לרוץ על כמה מערכות הפעלה בלי לקמפל מחדש עבור כל אחת; ה-CLR מוסיף ניהול זיכרון אוטומטי (Garbage Collector) שחוסך באגים נפוצים של דליפות זיכרון; ה-CLI מספק זרימת עבודה אחידה (new/run/build) שעובדת זהה בכל מערכת הפעלה.
חסרונות
שכבת ה-JIT מוסיפה עלות ריצה קלה בהשוואה לשפות שמקמפלות ישירות לקוד מכונה (כמו C++); שגיאות קומפילציה מתגלות רק כשמריצים dotnet build/run, לא תוך כדי כתיבה בעורך טקסט פשוט בלי IDE.
נקודות חשובות
• C# עוברת שני שלבים: קומפילציה ל-IL, ואז הרצה על ה-CLR עם JIT
• ה-CLR הוא מה שהופך .NET ל-cross-platform — אותו IL רץ בכל מערכת הפעלה שיש לה CLR
• dotnet run = dotnet build + הרצה, ברצף אחד
• Main (או Top-level statements) היא תמיד נקודת הכניסה של תוכנית קונסולה
טעויות נפוצות
• לבלבל בין “קוד המקור” (.cs) ל"קוד שרץ בפועל" (IL, שרק ה-CLR יודע להריץ)
• לחשוב ש-dotnet run “רק מריץ” — בפועל הוא גם מקמפל מחדש אם יש שינויים
• לשכוח ש-dotnet build בלבד לא מריץ כלום — רק בודק שהקוד תקין ומקמפל
סיכום
C# עוברת קומפילציה לקוד ביניים (IL) שה-CLR מריץ בפועל בזמן ריצה עם JIT — זו הסיבה שאותו קוד רץ בלי שינוי על Windows, Linux ו-Mac. .NET CLI (dotnet new/run/build) הוא הכלי שמנהל את כל התהליך הזה משורת הפקודה, ו-Main (או Top-level statements) הוא תמיד נקודת ההתחלה של כל תוכנית.
דוקומנטציה רשמית
Microsoft Learn — .NET CLI overview
Microsoft Learn — Common Language Runtime (CLR)
תרגילים
תרגיל 1 — יצירה והרצה ראשונה
המשימה: צרו פרויקט קונסולה חדש בשם HelloCSharp עם dotnet new console, שנו את השורה היחידה בקובץ כך שתדפיס את שמכם, והריצו עם dotnet run.
בדיקה: הפקודה dotnet run מדפיסה את שמכם לקונסולה בלי שגיאות.
תרגיל 2 — build מול run
המשימה: הריצו dotnet build בלבד (בלי run) על הפרויקט מתרגיל 1, ובדקו מה נוצר בתיקיית bin/.
בדיקה: אתם רואים קובץ .dll שנוצר בתיקיית bin/Debug/, אבל שום דבר לא הודפס לקונסולה — כי build מקמפל בלבד, לא מריץ.
פרויקט מסכם
המשימה: צרו תוכנית קונסולה שמדפיסה 3 שורות מידע על עצמה: שם התוכנית, גרסת .NET שמותקנת אצלכם (dotnet --version), ומשפט “התוכנית רצה בהצלחה”.
דרישות:
- שימוש ב-
dotnet new consoleליצירת הפרויקט - לפחות 3 קריאות נפרדות ל-
Console.WriteLine - הרצה מוצלחת עם
dotnet runללא שגיאות קומפילציה
בדיקה: הרצת dotnet run מדפיסה את שלוש השורות בסדר הנכון, בלי אזהרות או שגיאות קומפילציה בפלט.
מה בפרק הבא
בפרק הבא — משתנים וטיפוסים: איך שומרים ערכים בזיכרון, ולמה C# בודקת את סוג הערך כבר בזמן קומפילציה (Strong Static Typing) ולא מחכה לזמן ריצה כמו שפות דינמיות.