C sharp
C# (קרי: C sharp, סי שארפ) היא שפת תכנות מונחית עצמים, שפותחה על ידי צוות של חברת מיקרוסופט כחלק מיוזמת NET. שלה. בשנת 2005 ו־2006 תוקננה השפה על ידי הארגונים ECMA וארגון התקינה הבינלאומי. התחביר של C# מבוסס בעיקר על זה של שפות התכנות C++ ו־Java. באפריל 2010 פורסמה במקביל להצגת גרסה 4 של פלטפורמת NET., גרסת C# 4.
מקור שמה של שפת ++C מקורו באופרטור הקידום ++ שמשמעו "קידום באחד של המשתנה C". מקור השם #C הוא פרפראזה על כך, ומשמעו במוזיקה "הוספה של חצי טון לתו C" כלומר התו "דו דיאז". [1]
תוכן עניינים |
[עריכה] מערכת הטיפוסים
שפת C# היא שפה מונחית עצמים המאפשרת טיפוסיות חזקה, סטטית ובטוחה, אך תומכת (החל מגרסה 4) גם בטיפוסיות דינמית.
בדומה ל־Java ו־C++, ב־C# מתבצעת חלוקה של סוגי המשתנים לשני סוגים: טיפוסי מערכת המהווים חלק אינטגרלי משפת הפיתוח ומספריית .NET וטיפוסי משתמש המוגדרים/נבנים על ידי המתכנת.
[עריכה] עצמים
עצם הוא מופע של מבנה תכנותי הנקרא מחלקה. המחלקה מתארת מושג מופשט או מוחשי. למשל, בתוכנה לניהול מלאי במחסן, מחלקה יכולה לתאר פריט במחסן. מושג מופשט יכול להיות למשל מבנה נתונים בזיכרון המחשב.
כל סוגי המשתנים ב-C# הם עצמים, וזה כולל את הסוגים "הפרימיטיביים", כמו int (מספר שלם בן 32 סיביות), float, double (מספר בנקודה צפה בדיוק רגיל או כפול) ו-char (תו בודד). זאת בניגוד לשפת Java, בה הסוגים הפרימיטיביים אינם עצמים. כמו בשפת Java, כל המחלקות יורשות, ישירות או דרך מחלקות אחרות, מהמחלקה הראשית, שנקראת Object. האובייקטים הפרימיטיביים הם מבנים (structures) היורשים מ-Object דרך המחלקה ValueType.
בדומה ל־C++. ב-C# ניתן להוסיף למבנים שיטות (פונקציות השייכות למבנים או מחלקות נקראות "שיטות", Methods, כמו בשפות C++ ו-Java). מבנים יכולים לממש ממשקים (Interface), אך מחלקות ומבנים אחרים לא יכולים לרשת ממבנים, ומבנים תמיד יורשים ממחלקת ValueType בלבד.
[עריכה] משתני ערך לעומת משתני ייחוס
בדומה לשפת Java, ובניגוד ל-C++, המשתנים מתחלקים למשתני ערך (value types) ומשתני התייחסות (reference types). ההבדל העיקרי בין שני סוגים אלו, הוא באופן שבו הם מוחזקים בזיכרון. משתנה ערך מחזיק בערכו האמיתי בזיכרון המחסנית (במידה והוא לא מוכל עצם). לעומת זאת, במשתנה ייחוס, ההקצאה תעשה בחלק אחר של הזיכרון (ערימה) ובמחסנית תוחזק כתובתו של האובייקט (מצביע) ולא תוכנו. כתוצאה מכך, יש הבדל בהתנהגות משתנים משני הסוגים בעת העברת משתנה לפונקציה. בעת העברה לפונקציה, משתני ערך מועברים לעותק של המשתנה המקורי, וכל פעולה המתבצעת בפונקציה מבוצעת על העתק המשתנה, ולא במשתנה המקורי. כאשר משתני התייחסות מועברים לפונקציה, למעשה מועברת התייחסות (הכתובת בזיכרון) של המשתנה, והשינויים בערכו שמבוצעים בפונקציה מבוצעים על המשתנה המקורי.
בשפת C# האובייקטים היורשים ממחלקת ValueType מתנהגים כמו משתני ערך, בעוד שאובייקטים של מחלקות שאינן יורשות ממחלקה זו מתנהגים כמו משתני התייחסות. זאת בניגוד לשפת Java, בה המשתנים הפרימיטיביים הם משתני ערך, וכל האובייקטים הם משתני התייחסות עם זאת, ניתן בשפת C# לאלץ משתני ערך להתנהג כמו משתני התייחסות, פעולה שנקראת boxing.
[עריכה] עקרונות התכנות מונחה העצמים בשפה
בשפת C# ממומשים העקרונות הכלליים של התכנות מונחה העצמים: כימוס, הורשה ורב-צורתיות (פולימורפיזם). בשונה מ-C++ ובדומה ל-Java, ההורשה שמאפשרת C# יכולה להיות רק מטיפוס בסיס, ואין תמיכה בהורשה מרובה. לעומת זאת ישנה אפשרות לממש מספר "ממשקים" (Interfaces) שהם מעין חוזים המכריחים את המחלקות היורשות להכניס לתוכם את השיטות המוגדרות בממשק. הממשק לא כולל בתוכו מימוש כלשהו למתודות האלה, והמחלקה חייבת לממש אותן בעצמה.
בניגוד לשפת C++, ב-C# לא ניתן לכתוב פונקציות גלובליות. כל הפונקציות חייבות להיות מאוגדות במחלקות, ובפרט הפונקציה Main, שהיא נקודת הכניסה (ההתחלה) של התוכנית. בדומה לשפות C++ ו-Java, פונקציה יכולה להיות סטטית (static), אבל אז ניתן להפעיל אותה רק דרך שם המחלקה שלה ולא דרך עצם.
בC# ישנן 5 רמות הרשאה לגישה לשיטות. בנוסף ל-private, public ו-protected, המאפשרות בהתאמה, גישה מתוך המחלקה בלבד, גישה כללית, וגישה מתוך מחלקות יורשות, המקובלת ב-Java ו-C++, קיימת הרשאת internal מאפשרת גישה כללית רק מתוך היישום המשתמש במחלקה (ליתר דיוק, מתוך ה-Assembly של התוכנית, שהוא הקובץ הבינארי שאותו מריץ המחשב לאחר שהתוכנית עוברת הידור), והרשאת protected internal, המאפשרת גישה בתוך היישום ומתוך מחלקות יורשות, גם אם הן ב-Assembly אחר.
[עריכה] זיכרון מנוהל
במטרה למנוע זליגת זיכרון, שפת C#, כחלק מטכנולוגיית NET., מוגדרת כ"קוד מנוהל" (Managed Code). המתכנת פטור מן האחריות לשחרור מפורש של זיכרון המוקצה לאובייקט. סביבת ההרצה (CLR - Common Language Runtime) היא המופקדת על שחרור הזיכרון שתופסים עצמים שאינם בשימוש יותר.
לצורך כך, יוזמת סביבת ההרצה אחת לזמן מה תהליך של "איסוף זבל", הממפה את כל העצמים במערכת ומסמן למחיקה את אלו שאינם בשימוש. לצורך המיפוי מוגדרים מספר רכיבים ראשיים ("שורשים"). עצם הוא בשימוש אם הוא מוחזק על ידי אחד הרכיבים הראשיים, או שניתן להגיע אליו מאחד הרכיבים הראשיים דרך סדרה של עצמים אחרים. עצמים שאינם בשימוש מסומנים למחיקה. אם הוגדר עליהם קוד הרצה לפני מחיקה (Finalizer) הוא יבוצע. ולאחר מכן העצם ימחק והזיכרון אותו תפס ישוחרר.
זיכרון מנוהל אמור להבטיח ניצול של משאבי הזיכרון, אך הוא אינו מגן על משאבים אחרים כדוגמת גישה לבסיסי מידע, קבצים פתוחים וכדומה. בנוסף, זליגת זיכרון עדיין עלולה לקרות אם כתוצאה משגיאה בתוכנית ניתן לגשת אל עצמים גם כאשר אין בהם עוד צורך. מנגנון איסוף הזבל לא יכול לדעת שמדובר בשגיאה, ולא יפנה את העצמים מן הזיכרון.
[עריכה] תכונות - Properties
מוסכמה שכיחה ב-C++ היא לכנות שיטות שתפקידן השמה ואחזור של ערכים כ- get ו-set ולאחריהן שם התכונה. כדי להקל בנושא זה נלקח רעיון ה"תכונות" מ- Visual Basic, בו צורת ההשמה והאחזור היא פשוטה שקופה ואחידה. כל שנצרך להגדיר הוא הגבלת ההרשאה (Access Modifier) על פי רעיון הכימוס, להחליט מה יהיה הערך המוחזר ולקבוע את שם התכונה, ולאחר מכן לקבוע מה יקרה ב-get (אחזור הערך) ומה ב-set (השמת הערך). בזמן הריצה, בכל פעם שיתבקש מהתכונה ערך היא תפנה ל-get וכל פעם שיושם לה ערך היא תפנה ל-set. כמו כן, החל מגרסה 2.0, ניתן לתת רמות הרשאה שונות ל-get ול-set (כך, לדוגמה, ניתן לקבוע הרשאת גישה ציבורית לאחזור (get) אך להגביל את השמת הערך לתכונה (set) למחלקות יורשות בלבד).
[עריכה] העמסת אופרטורים
העמסת אופרטורים היא טכניקה המאפשרת לתת משמעות חדשה לאופרטורים שונים של השפה, כדי להקל על הקריאות של התוכנית. למשל: ניתן להעמיס את אופרטור החיבור + כדי שיבצע גם חיבור וקטורי.
C# מאפשרת העמסת אופרטורים, אך באופן מוגבל יותר מאשר ב-C++. ניתן להעמיס למשל את האופרטורים '+' ו-'==', אך לא את האופרטור "[ ]" (המשמש לגישה אל איבר במערך. ניתן, עם זאת, לכתוב למטרה זאת פונקציה בתחביר מיוחד, הנקראת indexer).
[עריכה] טיפול בחריגות
C# תומכת בטיפול בחריגות (מצבים לא תקינים במהלך הריצה של התוכנית) על ידי "זריקת" אובייקטים במעלה שרשרת הקריאות לפונקציה, כדי להעביר מידע על החריגה. בדומה לשפת Java, גם ב-C# אפשר לזרוק רק אובייקטים מסוג המחלקה Exception. בניגוד ל-Java, לא ניתן להכריז על שיטה כשיטה הזורקת חריגה, וכן אין חובה "לתפוס" חריגות שנזרקו - כל חריגה עשויה להתפס על ידי סביבת הריצה עצמה.
[עריכה] תאימות לאחור
כדי להקל על מפתחים להגר משפות אחרות, ובפרט משפת C++, אל שפת C#, נכללו בשפה "כינויים" למספר מחלקות ומבנים, הזהים לשמות המקבילים בשפת C++:
| מחלקה | כינוי |
|---|---|
| System.Byte | byte |
| System.Int16 | short |
| System.Int32 | int |
| System.Int64 | long |
| System.Single | float |
| System.Double | double |
| System.String | string |
| System.Boolean | bool |
| System.Char | char |
בנוסף, קיימים כינויים למחלקות שאינן קיימות כסוגי משתנים בשפת C++: הכינוי object למחלקה Object, וכן הקידומת unsigned משפת C++ תהיה בדרך כלל הקידומת u לכינוי המתאים (למעט byte, שהוא כבר unsigned, ולכן קיים הכינוי sbyte, שהוא byte עם סימן). למשל, unsigned int בשפת C++ מקביל ל-uint בשפת C#, שאינו אלא כינוי למבנה UInt32.
המבנה Char בשפת C# מכיל נתון באורך 16 סיביות או יותר (קידוד UTF-16), כדי שיוכל להכיל תו יוניקוד, בניגוד ל-char של C++ שהוא באורך 8 סיביות (ומכיל תו ANSI).
המבנה Int64 בשפת C# מכיל מספר שלם באורך 64 סיביות.
ניתן להשתמש בכינוי של מחלקה או בשם המפורש שלה, ללא כל משמעות מבחינת ריצת התוכנית.
[עריכה] דוגמה לתוכנית Hello world
להלן דוגמה לתוכנית Hello world בשפה זו[2]:
using System; public class ExampleClass { public static void Main(string[] args) { Console.WriteLine("Hello world!"); } }
[עריכה] ראו גם
[עריכה] קישורים חיצוניים
| מיזמי קרן ויקימדיה |
|---|
- תקן ECMA-334 המגדיר את שפת C#
- C++ -> C#: What You Need to Know to Move from C++ to C#, אתר msdn
- Ten Traps in C# for C++ Programmers, אתר ondotnet.com
[עריכה] הערות שוליים
- ^ Kovacs, James (September 7, 2007). C#/.NET History Lesson. אוחזר ב־June 18, 2009.
- ^ על מנת שהתוכנית תמתין לתגובה מהמשתמש, יש להוסיף את הפקודה ()Console.Read לאחר השורה השלישית מהסוף.