C sharp
| C# | |
|---|---|
| פרדיגמות | מרובת פרדיגמות: תכנות מונחה-עצמים, תכנות מבני, תכנות אימפרטיבי, תכנות פונקציונלי, תכנות מונחה-אירועים |
| מתכנן | חברת מיקרוסופט |
| מפתח | חברת מיקרוסופט |
| גרסה אחרונה | 5.0 (אוגוסט 2012) |
| טיפוסיות | חזקה, בטוחה, (סטטית עם תמיכה בטיפוסיות דינמית) |
| מימושים | Visual C#, Mono |
| ניבים | Cω, Spec#, Polyphonic C# |
| הושפעה על ידי | ++C, Smalltalk, Java, Visual Basic, אייפל, Modula-3 |
| השפיעה על | D, F#, Java, Nemerle, Vala |
| סיומת | cs. |
C# (קרי: C sharp, סי שארפ) היא שפת תכנות מרובת-פרדיגמות, שעיקרה מונחית עצמים, שפותחה על ידי צוות של חברת מיקרוסופט, כחלק מיוזמת NET. שלה. השפה הוצגה לראשונה בשנת 2000. בשנים 2005 ו־2006 תוקננה השפה על ידי הארגונים ECMA וארגון התקינה הבינלאומי. התחביר של C# מבוסס בעיקר על זה של שפות התכנות C++ ו־Java, אך הקונספט התכנותי שלה מושפע מ-VB[1]. באפריל 2010 פורסמה במקביל להצגת גרסה 4 של פלטפורמת NET., גרסת C# 4.
מקור שמה של שפת ++C מקורו באופרטור הקידום ++ שמשמעו "קידום באחד של המשתנה C". מקור השם #C הוא פרפראזה על כך, ומשמעו במוזיקה "הוספה של חצי טון לתו C" כלומר התו "דו דיאז". [2]
תוכן עניינים |
היסטוריה [עריכה]
לאחר שחברת מיקרוסופט הפסידה במשפט לחברת Sun על שימוש לא נאות בשפת Java, והיא הייתה מחויבת על פי פסק הדין להפסיק לשווק את סביבת ה-MS-JVM ואת שפת הפיתוח ++J, מיקרוסופט החלה בפיתוח שפת #C, אותה הציגה באמצע שנת 2000, כתחליף לשפה שנמנעה ממנה. תכונות רבות של השפה יושמו כבר בג'אווה (מכונה וירטואלית וקוד ביניים, הידור דינמי (JIT), ירושה יחידה עם ממשקים, זיכרון מנוהל ואי שימוש במצביעים, שיקוף (Reflection) ועוד), אך נוספו יכולות נוספות שאינן קיימות בג'אווה, ושנלקחו בעיקר משפת Visual Basic (תכונות, אירועים ועוד). היצירה של שפה חדשה לחלוטין אפשרה ללמוד משגיאות עיצוב בג'אווה, ללא שבירה של תאימות-לאחור, שמנעה תיקון של שגיאות אלה בשפת ג'אווה עצמה.
איפיוני השפה [עריכה]
שפת C# היא שפה מרובת-פרדיגמות, שהיא בעיקרה מונחית עצמים, אך ביחד עם זאת היא גם מונחת אירועים, ובעלת תמיכה בתכנות פונקציונלי.
השפה בעלת טיפוסיות חזקה. מערכת הטיפוסים בשפה היא סטטית - אך תומכת (החל מגרסה 4) גם בטיפוסיות דינמית - ובטוחה, אם כי מאפשרת גישה ישירה לזיכרון בעזרת מצביעים (בדומה לשפת C++) באזורים המכריזים על כך במפורש (Unsafe).
שפת #C נשענת על הNET Framework., הכוללת ספרייה סטנדרטית גדולה ועניפה, וסביבת זמן ריצה מתוחכמת.
שפה זו תומכת בהימשכות (Serialization) שבה נשמר רצף בין הזיכרון לדיסק, וניתן לשמור אובייקט לקובץ ולשחזר אותו מקובץ, במקביליות (Concurrency) שבה ניתן לבצע פעילות אסינכרונית של עצמים שונים. וכן מאפשרת התבוננות פנימה (Reflection), כלומר ניתן לחקור בזמן ריצה מאפיינים שונים הקשורים לשפה עצמה, למשל לבדוק מהו הטיפוס המדויק של אובייקט מסוים.
מערכת הטיפוסים [עריכה]
בדומה לשפות תכנות רבות, ב־C# מתבצעת חלוקה של סוגי המשתנים לשני סוגים: טיפוסי מערכת המהווים חלק אינטגרלי משפת הפיתוח ומספריית .NET וטיפוסי משתמש המוגדרים/נבנים על ידי המתכנת.
אובייקטים [עריכה]
עצם הוא מופע של מבנה תכנותי הנקרא מחלקה. המחלקה מתארת מושג מופשט או מוחשי. למשל, בתוכנה לניהול מלאי במחסן, מחלקה יכולה לתאר פריט במחסן. מושג מופשט יכול להיות למשל מבנה נתונים בזיכרון המחשב.
בניגוד לשפת Java ובדומה לשפת SmallTalk, כל סוגי המשתנים ב-C# הם עצמים, וזה כולל את הסוגים "הפרימיטיביים", כמו int (מספר שלם בן 32 סיביות), float, double (מספר בנקודה צפה בדיוק רגיל או כפול) ו-char (תו בודד). אולם כדי להימנע מהתקורה שהייתה נדרשת להגדרה אמתית של משתנים אלו כאובייקטים, בפועל משתנים אלו מוגדרים במחסנית כערכי Value type, וקיים מנגנון אריזה (Boxing) אוטומטי היודע להפוך אותם ל-reference type ולהתייחס אליהם כאל אובייקטים כאשר הדבר נצרך. כמו בשפת Java, כל המחלקות יורשות, ישירות או דרך מחלקות אחרות, מהמחלקה הראשית, שנקראת Object. האובייקטים הפרימיטיביים יורשים מ-Object דרך המחלקה ValueType.
בדומה ל־C++, ב-C# ניתן להוסיף למבנים שיטות (פונקציות השייכות למבנים או מחלקות נקראות "שיטות", Methods, כמו בשפות C++ ו-Java). מבנים יכולים לממש ממשקים (Interface), אך מחלקות ומבנים אחרים לא יכולים לרשת ממבנים, ומבנים תמיד יורשים ממחלקת ValueType בלבד.
משתני ערך לעומת משתני ייחוס [עריכה]
בדומה לשפת Java, ובניגוד ל-C++, האובייקטים מתחלקים לטיפוסי ערך (value types) וטיפוסי התייחסות (reference types). ההבדל העיקרי בין שני סוגים אלו, הוא באופן שבו האובייקט מועבר לפונקציה, או מועתק ממשתנה אחד לשני. בעת העברה לפונקציה, משתני ערך מועברים לעותק של המשתנה המקורי, וכל פעולה המתבצעת בפונקציה מבוצעת על העתק של האובייקט, ולא על האובייקט המקורי. כאשר אובייקט מטיפוס התייחסות מועברים לפונקציה, למעשה מועברת התייחסות אל האובייקט (מזהה המגדיר כיצד למצוא את האובייקט בזיכרון), וכל הפעולות מבוצעות על האובייקט המקורי (באופן דומה מעט לעבוד עם מצביעים בשפת C, או עם העבודה עם אובייקטים בג'אווה). בבררת המחדל של השפה, טיפוסי ערך הם: טיפוסים פרימיטיביים (למשל int), מונים (enumerators) ומבנים (structures). אילו טיפוסי התייחסות הם מחלקות, מערכים (arrays), נציגים (delegates) וממשקים.
בשפת C# האובייקטים היורשים ממחלקת ValueType מתנהגים כמו משתני ערך, בעוד שאובייקטים של מחלקות שאינן יורשות ממחלקה זו מתנהגים כמו משתני התייחסות. זאת בניגוד לשפת Java, בה המשתנים הפרימיטיביים הם משתני ערך, וכל האובייקטים הם משתני התייחסות. עם זאת, ניתן בשפת C# לאלץ משתני ערך להתנהג כמו משתני התייחסות, בפעולה שנקראת boxing.
עקרונות התכנות מונחה העצמים בשפה [עריכה]
בשפת C# ממומשים העקרונות הכלליים של התכנות מונחה העצמים: כימוס, הורשה ורב-צורתיות (פולימורפיזם). בשונה מ-C++ ובדומה ל-Java אין תמיכה בהורשה מרובה. לעומת זאת ישנה אפשרות לממש מספר "ממשקים" (Interfaces) שהם מעין חוזים המכריחים את המחלקות היורשות להכניס לתוכם את השיטות המוגדרות בממשק. הממשק לא כולל בתוכו מימוש כלשהו למתודות האלה, והמחלקה חייבת לממש אותן בעצמה.
למחלקה בשפה ניתן לכתוב שיטה בונה (Constructor) שמופעלת כאשר נוצר מופע ושיטה הורסת (Finalizer) שמופעלת לפני מחיקת המופע. כבררת מחדל קיימות בשפה שיטות בונה והורסת אוטומטית, שהינה שיטה ריקה, אם לא נכתבה אחת כזו בידי המתכנת. ניתן ליצור מספר רב של שיטות בונות באמצעות העמסת פרמטרים. בנוסף לקבוע (const) שמאותחל בזמן הידור, קיים קבוע נוסף (readonly) שיכול להיות מאותחל בזמן ריצה באמצעות השיטה הבונה. לרוב אין שימוש לFinalizer, שכן לא ידוע מתי הוא ייקרא על ידי מנגנון איסוף הזבל.
ב-C# ישנן חמש רמות הרשאה לגישה לשיטות. בנוסף ל-private, public ו-protected, המאפשרות בהתאמה, גישה מתוך המחלקה בלבד, גישה כללית, וגישה מתוך מחלקות יורשות, המקובלת ב-Java ו-C++, קיימת הרשאת internal המאפשרת גישה כללית רק מתוך ה-Assembly של המחלקה, שהוא הקובץ הבינארי שאותו מריץ המחשב לאחר שהתוכנית עוברת הידור, והרשאת protected internal, המאפשרת גישה בתוך היישום ומתוך מחלקות יורשות, גם אם הן ב-Assembly אחר.
ניתן למנוע ממחלקה להגדיר עצמים בעצמה, ולאפשר הגדרת עצמים באמצעות ירושתה במחלקות נגזרות, באמצעות הגדרתה כמחלקה אבסטרקטית (abstract). בדומה ל-Java ניתן להגדיר מחלקה שמנועה מירושה על ידי הגדרתה כמחלקה אטומה (sealed), וניתן למנועה דריסה של שיטה במחלקה נגזרת על ידי הגדרתה כשיטה אטומה (sealed) במחלקת הבסיס.
ניתן להגדיר מחלקה כמחלקה סדרנית (Indexers), שכומסת בתוכה מבנה נתונים כדוגמת מערך, שניתן להתייחס אליו במבנה החיצוני שלה כאילו שהייתה בעצמה מבנה נתונים עם אינדקס. דבר שאמור להפוך את ההתייחסות אליה ליותר אינטואטיבית.
ניתן לפצל קוד במחלקות חלקיות (partial), שהן מחלקות שמוגדרות במספר מקומות (ואף במספר קבצים), וכן ניתן ליצור שיטות חלקיות (במחלקה אחת רק הגדרה, ובמחלקה שנייה את המימוש).
בשפה יש תמיכה מובנת ב"תכונות" (Attributes) שמאפשרים להגדיר מגוון רחב של דברים בקוד התכנותי, כמו תכונות של מחלקות, שיטות ומשתנים, תהליכים תכנותיים ועד הסבר מובנה. דבר זה מייתר שימוש בקובצי הגדרה חיצוניים כמו קובצי DEF ו-IDL.
ניתן ליצור מחלקות מקוננות, ואף ליצור מופע של מחלקה מקוננת, ללא יצירת מופע של המחלקה המקננת. שיטה זו שונה משפת Java בה הגדרת עצם של מחלקה מקוננת, גורמת ליצירת מופע של המחלקה המכילה.
שיטות - Method [עריכה]
שפת C# היא מונחת עצמים טהורה, וכל דבר בה מוגדר כאובייקט, ואפילו משתנים פרימיטיביים, ולכן לא ניתן לכתוב פונקציות גלובליות או להגדיר משתנים גלובליים כמו בשפת C++ ו-VB. כל השיטות חייבות להיות מאוגדות במחלקות, ובפרט הפונקציה Main, שהיא נקודת הכניסה (ההתחלה) של התוכנית.
התחליף לשיטה גלובלית הוא בכתיבת פונקציה סטטית (static), שמופעלת דרך שם המחלקה שלה בלי הצורך ליצור מופע, והפתרון למשתנה גלובלי הוא משתנה סטטי במחלקה כלשהי. שיטה סטטית איננה יכולה לגשת למשתנים רגילים, אך יכולה לגשת למשתנים סטטיים, שאותם ניתן לאתחל באמצעות בונה סטטי. במידה וכל הפונקציות במחלקה הן סטטיות ניתן להגדיר את המחלקה עצמה כמחלקה סטטית.
C# מאפשרת העמסת שיטות, שהיא האפשרות לכתוב שיטות בעלות שם זהה, וחתימה שונה (רשימת הפרמטרים צריכה להיות שונה בטיפוסי הפרמטרים או במספרם). כמו כן ניתן ליצור שיטה עם מספר לא ידוע של פרמטרים (באמצעות מילת המפתח params והגדרת מערך ברשימת הפרמטרים. (לדוגמה: (public void functionName(params String[] str1). גם ניתן ליצור ערכי בררת מחדל בפרמטרים של שיטה באופן דומה לכתיבה ב-C#.
השפה מאפשרת החזרת ערך של ריבוי פרמטרים בשיטה באמצעות הגדרתן ב-ref או כ-out, שמשמעותם שהפרמטרים הועברו כמצביעים. העברת משתנה כ-ref מחייבת איתחולו לפני הפעלת השיטה, בעוד שהעברתו כ-out אינה מחייבת איתחול.
מאפיינים - Properties [עריכה]
מוסכמה שכיחה ב-C++ היא לכנות שיטות שתפקידן השמה ואחזור של ערכים כ-get ו-set ולאחריהן שם התכונה. כדי להקל בנושא זה נלקח רעיון ה"מאפיינים" מ- Visual Basic, בו צורת ההשמה והאחזור היא פשוטה שקופה ואחידה. בתפיסה זו מאפיין מורכב משדה ושתי שיטות הפועלות עליו: האחת קוראת ממנו (getter) והאחת כותבת אליו (setter). כל שנצרך להגדיר הוא הגבלת ההרשאה (Access Modifier) על פי רעיון הכימוס, להחליט מה יהיה הערך המוחזר ולקבוע את שם המאפיין, ולאחר מכן לקבוע מה יקרה ב-get (אחזור הערך) ומה ב-set (השמת הערך). בזמן הריצה, בכל פעם שיתבקש מהמאפיין ערך היא תפנה ל-get וכל פעם שיושם לה ערך היא תפנה ל-set. כמו כן, החל מגרסה 2.0, ניתן לתת רמות הרשאה שונות ל-get ול-set (כך, לדוגמה, ניתן לקבוע הרשאת גישה ציבורית לאחזור (get) אך להגביל את השמת הערך לתכונה (set) למחלקות יורשות בלבד). בנוסף לכך שהמאפיינים מהווים רמת הפשטה למשתמש במחלקה, הם הופכים את השדה לשדה חכם (smart field) שמאפשר לבצע פעולות נוספות בעת השמה או קלט, כמו למשל ביצוע בדיקות או אתחול עצל, שהוא אתחול בזמן שימוש בשדה ולא בזמן יצירת המחלקה, וכן הגבלה על כתיבה או קריאה לשדה.
אירועים - Events [עריכה]
בכדי שיהיה אפשר לתקשר ולהעביר מידע בין מחלקות שונות משתמשים בשפת C++ ב-Callback Function. בשפת C# בעקבות שפת VB רעיון זה מומש באמצעות אירועים. במחלקה השולחת ניתן ליצור אירועים (שהם למעשה delegates, המצביעים לפונקציות) ולהזניק אותם במקום הרלוונטי באמצעות קריאה בשמם, ובמחלקה המקבלת ניתן ללכוד אירועים אלו באמצעות רישום פונקציה מקומית (בעלת חתימה זהה) לאירוע. התוצאה היא שבעת שאירוע מוזנק במחלקה השולחת, הוא גורם למעשה להרצת הפונקציה במחלקה המקבלת. ניתן לרשום מספר רב של פונקציות לאירוע מסוים, ומספר רב של אירועים לפונקציה אחת.
העמסת אופרטורים [עריכה]
C# מאפשרת העמסת אופרטורים - שהיא טכניקה המאפשרת לתת משמעות חדשה לאופרטורים קיימים בשפה, כדי להקל על הקריאות של התוכנית - אך באופן מוגבל יותר מאשר ב-C++. ניתן להעמיס למשל את האופרטורים '+' ו-'==', אך לא את האופרטור "[ ]" (המשמש לגישה אל איבר במערך. ניתן, עם זאת, לכתוב למטרה זאת פונקציה בתחביר מיוחד, הנקראת indexer).
זיכרון מנוהל [עריכה]
במטרה למנוע בעיות הנובעות מניהול עצמאי של זיכרון כמו זליגת זיכרון ודריסת זיכרון, שפת C#, כחלק מטכנולוגיית NET., מוגדרת כ"קוד מנוהל" (Managed Code). המתכנת פטור מן האחריות לשחרור מפורש של זיכרון המוקצה לאובייקט. סביבת ההרצה (CLR - Common Language Runtime) היא המופקדת על שחרור הזיכרון שתופסים עצמים שאינם בשימוש יותר.
לצורך כך, יוזמת סביבת ההרצה אחת לזמן מה תהליך של "איסוף זבל" (Garbage collection), הממפה את כל העצמים במערכת ומסמן למחיקה את אלו שאינם בשימוש. לצורך המיפוי מוגדרים מספר רכיבים ראשיים ("שורשים"). עצם הוא בשימוש אם הוא מוחזק על ידי אחד הרכיבים הראשיים, או שניתן להגיע אליו מאחד הרכיבים הראשיים דרך סדרה של עצמים אחרים. עצמים שאינם בשימוש מסומנים למחיקה. אם הוגדר עליהם קוד הרצה לפני מחיקה (Finalizer) הוא יבוצע. ולאחר מכן העצם ימחק והזיכרון אותו תפס ישוחרר.
זיכרון מנוהל אמור להבטיח ניצול של משאבי הזיכרון, אך הוא אינו מגן על משאבים אחרים כדוגמת גישה לבסיסי מידע, קבצים פתוחים וכדומה. בנוסף, זליגת זיכרון עדיין עלולה לקרות אם כתוצאה משגיאה בתוכנית ניתן לגשת אל עצמים גם כאשר אין בהם עוד צורך. מנגנון איסוף הזבל לא יכול לדעת שמדובר בשגיאה, ולא יפנה את העצמים מן הזיכרון.
טיפול בחריגות [עריכה]
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 סיביות.
ניתן להשתמש בכינוי של מחלקה או בשם המפורש שלה, ללא כל משמעות מבחינת ריצת התוכנית.
גרסאות [עריכה]
ל-C# פורסמו מספר מהדורות, בדרך כלל בצמוד להפצת מהדורה חדשה של ויז'ואל סטודיו:
| גרסה | תאריך | .NET Framework | ויז'ואל סטודיו |
|---|---|---|---|
| C# 1.0 | ינואר 2002 | .NET Framework 1.0 | Visual Studio .NET 2002 |
| C# 1.2 | אפריל 2003 | .NET Framework 1.1 | Visual Studio .NET 2003 |
| C# 2.0 | נובמבר 2005 | .NET Framework 2.0 | Visual Studio 2005 |
| C# 3.0 | נובמבר 2007 | .NET Framework 3.0 .NET Framework 3.5 |
Visual Studio 2008 Visual Studio 2010 |
| C# 4.0 | אפריל 2010 | .NET Framework 4 | Visual Studio 2010 |
| C# 5.0 | אוגוסט 2012 | .NET Framework 4.5 | Visual Studio 2012 |
דוגמה לתוכנית Hello world [עריכה]
להלן דוגמה לתוכנית Hello world בשפה זו[3]:
using System; public class ExampleClass { public static void Main(string[] args) { Console.WriteLine("Hello world!"); } }
ראו גם [עריכה]
לקריאה נוספת [עריכה]
- כריסטוף וייל, היכרות עם C#, בהוצאת SAMS והוד עמי, ישראל 2001, 189 עמ'
- טום ארצ'ר, C# למתכנתי Java/C++/Visual C++, הוצאת מיקרוסופט והוד עמי, ישראל 2002, 411 עמ'
- דאנקן מקניז, וקנט שארקי, C# - סדנת לימוד, SAMS והוצאת הוד עמי, ישראל 2002, 800 עמ'
- על כוס קפה, מדריך לשפת C# ולמערכת .NET , עיטם מדעי המחשב, 2011
קישורים חיצוניים [עריכה]
| מיזמי קרן ויקימדיה |
|---|
- תקן 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
הערות שוליים [עריכה]
- ^ "C# משלבת את היצרנות הגבוהה של Microsoft Visual Basic עם העוצמה הגלומה ב-C++" סקוט וויילטמוף (חבר בצוות הפיתוח של השפה) מצוטט ב-C# למתכנתי Java/C++/Visual C++, הוצאת מיקרוסופט והוד עמי, ישראל 2002, עמ' 14
- ^ Kovacs, James (September 7, 2007). C#/.NET History Lesson. אוחזר ב־June 18, 2009.
- ^ על מנת שהתוכנית תמתין לתגובה מהמשתמש, יש להוסיף את הפקודה ()Console.Read לאחר השורה השלישית מהסוף.