סי שארפ – הבדלי גרסאות

מתוך ויקיפדיה, האנציקלופדיה החופשית
תוכן שנמחק תוכן שנוסף
מ ←‏ירושה: כפי שאמר אחד ממתכנני השפה, "מחלקה סטטית" זה שם אחר ל"מודול"
לא חוקי בתחביר
שורה 1: שורה 1:
{{שם שגוי|#C}}
{{שפת תכנות
{{שפת תכנות
|שם = C#{{D}}
|שם = C#{{D}}

גרסה מ־20:08, 20 במאי 2016


שגיאות פרמטריות בתבנית:שפת תכנות

פרמטרים ריקים [ אתר ] לא מופיעים בהגדרת התבנית

פרמטרים [ לוגו, שנה ] לא מופיעים בהגדרת התבנית

C#‎
פרדיגמות מרובת פרדיגמות: מונחת-עצמים, אימפרטיבית, רפלקטיבית, פונקציונלית, מבנית, מונחת אירועים וגנרית.
תאריך השקה 2001 עריכת הנתון בוויקינתונים
מתכנן חברת מיקרוסופט
מפתח חברת מיקרוסופט
גרסה אחרונה 12.0 (14 בנובמבר 2023) עריכת הנתון בוויקינתונים, C# 2.0, C# 3.0, C# 4.0 עריכת הנתון בוויקינתונים
טיפוסיות חזקה, בטוחה, (סטטית עם תמיכה בטיפוסיות דינמית)
מימושים Visual C#, Mono, Xamarin, Cordova
ניבים Cω, Spec#, Polyphonic C#
הושפעה על ידי ++C,‏ Smalltalk,‏ Java,‏ Visual Basic, אייפל, Modula-3
השפיעה על סוויפט (שפת תכנות),D‏, F#, Java, Nemerle, Vala
סיומת cs.
https://docs.microsoft.com/de-de/dotnet/csharp/, https://docs.microsoft.com/ja-jp/dotnet/csharp/, https://docs.microsoft.com/fr-fr/dotnet/csharp/, https://docs.microsoft.com/it-it/dotnet/csharp/ האתר הרשמי
לעריכה בוויקינתונים שמשמש מקור לחלק מהמידע בתבנית

C#‎ (נהוג לבטא C Sharp או "סִי שַׁארפּ") היא שפת תכנות עילית מרובת-פרדיגמות, מונחית עצמים בעיקרה, המשלבת רעיונות כמו טיפוסיות חזקה, אימפרטיביות, הצהרתיות, פונקציונליות, פרוצדורליות וגנריות. השפה פותחה על ידי מיקרוסופט בשנת 2000 כחלק מפרויקט דוט נט ותוקננה בשנים 2005 ו-2006 על ידי ארגון התקינה Ecma כתקן ECMA-334 ועל ידי ארגון התקינה הבינלאומי (איזו) כתקן ISO/IEC 23270:2006.

היסטוריה

אנדרס היילסברג - האדריכל הראשי של C#. איש בורלנד לשעבר שהישגו הראשון במיקרוסופט היה ניהול הפיתוח של J++‎

לאחר הפסדה של מיקרוסופט במשפט לחברת סאן, בעקבות סכסוך שפרץ ביניהן סביב המימוש של מיקרוסופט לשפת Java, שנקרא J++‎, חויבה מיקרוסופט על פי פסק הדין להפסיק לשווק את J++‎ וכן את המכונה הווירטואלית שפיתחה עבורה, MS-JVM. עקב כך הוחלט במיקרוסופט על פיתוח שפה חדשה במטרה להוות תחליף ראוי לשפות התכנות מהדור הקודם כמו ויז'ואל בייסיק או C++‎ וכן להוות יריב שקול ל-Java. צוות פיתוח בראשות מהנדס התוכנה הדני אנדרס היילסברג (מי שהמציא את טורבו פסקל והיה מאדריכלי דלפי) הופקד על פיתוחה בתחילת 1999, והגרסה הראשונה הושקה עם ההכרזה על דוט נט ביולי 2000[1]. גרסה זו סיפקה את התשתית הראשונית לכתיבת יישומים שולחניים ואתרי אינטרנט, תוך שהיא שואבת הרבה מה-API והתחביר של Java, גם בטכנולוגיית פיתוח האתרים, ASP.NET.

גרסה 1.1, אשר יצאה ב-3 באפריל 2003, הכילה שיפורים בטכנולוגיית ASP.NET אשר מאפשרים פיתוח אתרים המותאמים למכשירים ניידים, שיפורי אבטחה בפיתוח יישומים שולחניים, תמיכה מובנית בגישה לבסיס נתונים אורקל ובשימוש במתאם בסיסי הנתונים האוניברסלי של מיקרוסופט, ODBC. גרסה זו גם תומכת בהפעלה של מספר גרסאות של אותו יישום במקביל על אותו מחשב, וכן תומכת לראשונה בפרוטוקול IPv6.

גרסה 2.0, אשר יצאה ב-22 בינואר 2006, הוסיפה לראשונה תמיכה בתכנות גנרי, שהיה קיים כבר ב-C++. גרסה זו תמכה לראשונה ביישומי 64 ביט. בנוסף, נוספה תמיכה מובנית לגישה למערכת ההרשאות של Windows, ונוספו שיפורים בטכנולוגיית הגישה לבסיסי נתונים ADO.NET. בתחום פיתוח האתרים, נוספו מנגנונים אשר מאפשרים לשלוט בצורה טובה יותר בתבנית הכללית של כל הדפים באתר. נוספה תמיכה מובנית בתקשורת SSL, ותמיכה בפרוטוקול FTP‎, Ping, SMTP ו-SOAP 1.2. שופרה התמיכה בטכנולוגיית COM וביישומי שורת הפקודה. נוספה תמיכה בקבלת חיבורי HTTP ו-FTP מיישומים אחרים. שופרה התמיכה בסמפור, ונוספה תמיכה בטרנזאקציות דרך טכנולוגיית DTC. פקדים רבים נוספו לפיתוח תוכנות שולחניות, ונוספה טכנולוגיית ClickOnce, אשר מאפשרת ליישומים שולחניים להתעדכן באופן אוטומטי.

גרסה 3 אשר יצאה בנובמבר 2007 הוסיפה הרחבת שיטות, (שמאפשר בזמן ריצה להוסיף שיטות לאובייקטים קיימים), טיפוס מרומז של משתנים מקומיים, ביטויי למדא, טיפוסים אנונימיים, טיפוס ממשק (Type Inference), ואיתחול של אובייקטים ואוספים (בגרסאות הדוט נט המקבילות הוספו WCF, WPF וLINQ).

גרסה 4 אשר יצאה באפריל 2010 הוסיפה פרמטרים לפי שם ופרמטרים אופציונליים, טיפוסים דינמיים, ותמיכה מתקדמת ב-COM (בגרסת הדוט נט המקבילה הוספו יכולות של תכנות מקבילי, איתחול עצל, ומהדר DLR).

גרסה 5 אשר יצאה באוגוסט 2012 הוסיפה פונקציות אסינכרוניות, ומידע על המתקשר לפונקציה.

ב-2 באפריל 2014 שחררה מיקרוסופט מהדר סטטי בשם DotNET Native ליישומי Windows Store, המאפשר להדר קוד בשפות הדוט נט לקוד מכונה באופן ישיר (Native Code), ללא שימוש ב-J.

בגרסה 6 אשר יצאה ביולי 2015 הוספו התכונות הבאות: הידור כשירות (service), יבוא של טיפוסים סטטיים למרחב שם, מסנן לחריגות, אתחול אוטומטי של מאפיין לקריאה בלבד, אתחול של מילון, Await בבלוק של catch/finally, אינטרפולציה על מחרוזת והאופרטור nameof.

הדמיון ל-Java

קיימים קווי דמיון רבים מאוד בין שפת C#‎ ל-Java, כגון; אובייקטים כהפניות (References), קוד ביניים ומכונה וירטואלית, הידור דינמי (JIT), ירושה יחידה עם ממשקים, זיכרון מנוהל ופינוי אשפה, שיקוף, Boxing, תהליכונים מובנים, יוניקוד מובנה, צורת השימוש בספריות ועוד. ובכל זאת, קיימים הבדלים גדולים בין השתיים. בעיקר בהגדרת אופן מימוש מנגנוני השפה, השוני במימוש תכנות גנרי. מלבד זאת בסי שארפ נוספו תכונות שבחלקן אומצו מ-VB כגון תכנות ויז'ואלי, תכנות מונחה אירועים, אתחול אוטומטי של משתנים, משתנה רב תכליתי, מאפיינים, לולאת טווח ועוד. במיוחד גדל הפער בין השפות בגרסאות החדשות של סי שארפ בהן נוספו הרחבות כמו תכנות פונקציונלי, מתודות-הרחבה (Extension methods) והרחבת LINQ.

פיתוח השפה היה ראשוני, ונטול עכבות היסטוריים כמו תאימות לאחור, שהיקשה על האבולוציה של Java. ברור גם כי העובדה ש-C#‎ פותחה אחרי Java איפשרה למיקרוסופט ללמוד מהחסרונות והיתרונות שלה וליישם את הלקחים בשפה החדשה[2].

אנשי סאן טענו כי מיקרוסופט גנבה לא מעט רעיונות משפת Java. לטענתם, C#‎ היא בעצם חיקוי לא מוצלח של Java ממנו הוסרו אמינות, יצרנות ואבטחה[3]. במיקרוסופט מתעקשים לעומת זאת כי השפה דומה יותר ל-C++‎ מאשר ל-Java.

ההבדל המהותי ביותר בין #C ל- Java הוא מתודולוגי, #C היא שפה מונחית עצמים טהורה (Pure Object Oriented), ב- #C כל דבר הוא אובייקט, אפילו הטיפוסים הפשוטים (int, double, float, char ועוד) הם אובייקטים. Java לעומת זאת, היא אמנם מונחית עצמים אולם היא לא שפה מונחית עצמים טהורה, הטיפוסים הפשוטים הם פרימיטיביים (כמו ב-C), והיא לא מבחינה בין מתודות וירטואליות למתודות לא וירטואליות ועוד.

יעדי השפה

תקן EMCA מפרט את יעדי הפיתוח של השפה:

  • הפשטה: השפה צריכה להיות פשוטה להבנה וכתיבה, דינאמית, גנרית, מודרנית ומונחית עצמים טהורה במידת האפשר.
  • הנדסה: השפה ויישומה צריכים לספק תמיכה בעקרונות הנדסת תוכנה מתקדמים כמו בדיקת טיפוסיות, בדיקת חריגות גבול, מנגנון לאיתור שימוש במשתנים לא מאותחלים ואיסוף זבל.
  • פריסה: השפה צריכה לתמוך בפיתוח יישומים המתאימים להתקנה בסביבה מבוזרת - קרי, הפעלה בכל מערכת בה מותקנים רכיבי זמן ריצה מתאימים.
  • פורטביליות: שימת דגש על ניידות הקוד כמו גם פורטביליות המתכנת, במיוחד הקלת המעבר לאלו שהתנסו בכתיבה בשפות C ו-C++‎.
  • בינלאומיות: תמיכה בריבוי שפות כמו גם שפות שמיות (ימין לשמאל ושמאל לימין).
  • מודולריות: השפה צריכה להתאים למערכות שונות, ממערכות גדולות בעלות פונקציונליות מרובה דרך מחשב ביתי ועד למערכות משובצות מחשב ייעודיות קטנות.
  • ביצועיות: למרות היותה חסכונית במונחים של צריכת זיכרון וזמן עיבוד, היא אינה מתחרה ישירות בשפות C / C++‎ או שפת סף.

התחביר של C#‎ מבוסס בעיקרו על שפת התכנות C++‎ אך הקונספט התכנותי הושפע רבות מ-VB[4] ו-Java. מהם אומצו מספר מוטיבים כמו תכנות מונחה-אירועים, תכנות הצהרתי, תכנות פונקציונלי ותכנות גנרי.

איפיוני השפה

מקור שמה הוא פרפראזה על מקור שמה של C++ שהוא אופרטור הקידום שמשמעו "קידום ערך באחד" או בהקשר זה קידום שפת C רמה אחת מעל. במוזיקה משמעות C#‎ היא הוספה של חצי טון לתו C (או "דו דיאז"). רעיון השימוש בסולמית אומץ על ידי מיקרוסופט כסיומת נפוצה לטכנולוגיות אחרות מבית החברה שעברו שיפוץ.

שפת #C תוכננה במטרה להשתלב בתשתית NET. הכוללת ספרייה סטנדרטית גדולה וסביבת זמן ריצה. עם זאת, השפה איננה דורשת את NET. וקיימת מערכת מקבילה לסביבת לינוקס בשם Mono. ומערכת בשם זמרין לסביבת אנדרואיד.

קוד של C#‎ מחשב שורשים של פונקציה בעזרת שיטת ניוטון-רפסון ושיטת החצייה.

בשפה שולבו מספר מאפיינים בולטים שהם חלק אינטגרלי מהקונספט הטכנולוגי של דוט נט:

  • תמיכה בסריאליזציה‏[5] שבה נשמר רצף בין הזיכרון לדיסק, כך ניתן לשמור אובייקט לקובץ ולשחזר אותו.
  • מקביליות (Concurrency) שבה ניתן לבצע פעילות אסינכרונית של עצמים שונים.
  • התבוננות פנימה (Reflection), כלומר חקירת מאפיינים שונים הקשורים לשפה עצמה בזמן ריצה, למשל לבדוק מהו הטיפוס המדויק של אובייקט נתון. באמצעות תכונה זו ניתן למשל להחליף שם של משתנה בכל המרחב, לעטוף שדה באמצעות תכונה, או להוציא חלק מקוד לפונקציה חדשה.
  • תכונות (Attributes) שמאפשרים להגדיר מגוון רחב של עזרים בקוד התכנותי, כמו פירוט תכונות של מחלקות, שיטות ומשתנים, הגדרת תהליכים תכנותיים ועד הסבר מובנה. מה שמייתר צורך בקובצי הגדרה חיצוניים כמו DEF ו-IDL.
  • אירועים (Events) שמאפשרים לרשום פונקציות לאירועים, ולהזניק הודעות מאובייקט אחד לשני.
  • מבנה השפה. ההיררכיה של קוד בC# מתחילה בפתרון (Solution) שיכול לאגד בתוכו פרויקטים (Project). כל פרויקט יכול לאגד בתוכו מחלקות (class). כל מחלקה יכולה להכיל בתוכה פונקציות (Function). פונקציות יכולות להיות משויכות לתחום מסוים (namespace).

מערכת הטיפוסים

הטיפוסיות בשפה היא סטטית (עם תמיכה בפולימורפיזם של זמן ריצה), ותמיכה בטיפוס dynamic, המאפשר עבודה ב"טיפוסיות-ברווז" דינמית[6].

מערכת הטיפוסים היא חזקה ובטוחה, למעט באזורים בקוד המסומנים באמצעות המילה השמורה unsafe. באזורים אלה מתאפשרת גישה ישירה לזיכרון בעזרת מצביעים (בדומה לשפת C++‎)[7].

על פי רוב, טיפוסי המשתנים מוגדרים במפורש, אך בהקשרים רבים ניתן להשתמש במילה השמורה var על מנת לבקש מהמהדר להסיק אותם בעצמו.[8] כמו כן, ישנה הסקה מובלעת של טיפוסים במבנים תחביריים שונים כגון ביטויי למדא.[9]

משתני ערך לעומת משתני ייחוס

בשפת #C ישנה חלוקה של הטיפוסים לשני סוגים:[10]

  • טיפוסי התייחסות (Reference Types): בעלי סמנטיקת התייחסות, בדומה למצב בשפת ג'אווה. מחלקות, מערכים, נציגים (delegates) ממשקים, טיפוסים דינמיים ומחרוזות הם טיפוסי התייחסות.[11]
  • טיפוסי ערך (Value Types): בעלי סמנטיקת ערך, בדומה למצב בשפת ++C. טיפוסי ערך יורשים מהמחלקה ValueType (שבתורה יורשת מ-object). טיפוסי ערך הם מבנים (struct),‏ enum, והטיפוסים הפרימיטיביים (כגון int‏, double ו-‏char).[12]. עבור טיפוסי ערך קיים מנגנון אריזה (Boxing) ההופך אותם לטיפוסי התייחסות כאשר הדבר נדרש.[13]

ההבדל העיקרי בין שני סוגים אלו הוא באופן שבו אובייקט מועתק (בפעולת השמה או בהעברה כפרמטר). בהעתקת משתנה ערך מועתק האובייקט עצמו, וכל פעולה המתבצעת בפונקציה מבוצעת על העותק, ולא על האובייקט המקורי. בהעתקת אובייקט מטיפוס התייחסות, מועתק רפרנס (מזהה המגדיר כיצד למצוא את האובייקט בזיכרון), וכל פעולה שאיננה העתקה מבוצעת על האובייקט המקורי (באופן דומה מעט לעבודה עם מצביעים בשפת C).

בדומה למחלקה, גם מבנים יכולים להכיל קבועים, שדות, תכונות, מתודות, אופרטורים, אירועים ואף לממש ממשקים, אך לא ניתן להגדיר עבורם ירושה.

בעוד שמחלקה היא מבנה התכנות העיקרי, מבנים מיועדים לעטוף קבוצות קטנות של משתנים קשורים, בעיקר כאלה שאינם אמורים להשתנות לאחר היצירה של האובייקט.[14]

אין לבלבל בין טיפוסי ערך והתייחסות ובין העברת פרמטרים על פי ערך ועל פי התייחסות (ר' בהמשך).

העברת פרמטרים

ברירת המחדל של העברת פרמטרים למתודה היא על ידי העתקה: אובייקט מטיפוס ערך מועתק בעצמו, ועבור אובייקט מטיפוס התייחסות מועתקת ההתייחסות אליו.[15] ניתן לשלוט על כך באמצעות הגדרת הפרמטרים כ-ref או כ-out (הן במתודה והן בקריאה אליה). פרמטר המוגדר כאחד מהם דורש משתנה ממש (או ביטוי שניתן לבצע אליו השמה - lvalue. ולא אובייקט); משתנה זה מועבר בעצמו - ללא העתקה - ופעולות השמה בתוך המתודה מתבצעות ישירות עליו.

  • העברת משתנה כ-ref מחייבת אתחולו לפני הפעלת המתודה, והמתודה רשאית לקרוא ממנו או לכתוב אליו.[16]
  • העברת משתנה כ-out מאפשרת לדמות החזרה של מספר ערכים מהמתודה. המתודה איננה רשאית לקרוא מהמשתנה אלא רק לכתוב אליו.[17]

ניתן להגדיר מתודה המקבלת מספר משתנה של פרמטרים בעזרת המילה השמורה params.[18]

סוגי משתנים

ניתן להגדיר משתנה קבוע (const) המאותחל בזמן הקישור[19], אשר בקוד ה-MSIL יוחלף לערכו . ניתן להגדיר משתנה קריאה-בלבד (readonly) היכול להיות מאותחל בזמן ריצה באמצעות הבנאי[20], וערכו אינו נשמר בקוד ה-MSIL, בניגוד לקבוע.

תכנות מונחה-עצמים

שפת C#‎ היא שפה מונחית-עצמים, התומכת בכימוס (Encapsulation), בירושה ובפולימורפיזם של זמן ריצה.

ירושה

בשפת #C כל מחלקה יורשת ממחלקה בודדת, וישנה אפשרות לממש מספר ממשקים (Interfaces): מחלקות הכוללות מתודות אבסטרקטיות בלבד, ומשמשות כחוזים המכריחים את המחלקות היורשות לממש את המתודות המוגדרות בממשק. ב#C קיימת ירושה ציבורית בלבד; לא ניתן להחיל הגבלות גישה על מחלקות האם.

סוגים שונים של מחלקות:[21]

  • מחלקה אבסטרקטית (abstract) היא מחלקה המשמשת כמחלקת אם בלבד; לא ניתן ליצור עצמים של המחלקה שלא דרך מחלקה יורשת, והיא מגדירה טיפוס משותף, ממשק משותף (אם מוגדרות בה מתודות) ומימוש ברירת מחדל (אם מוגדרות בה מתודות לא-אבסטרקטיות או משתנים) עבור מחלקות יורשות.
  • מחלקה חתומה (sealed): מחלקה שלא ניתן לרשת ממנה (מקביל ל-final בג'אווה).[22]
  • מחלקה סטטית: מודול. מחלקה שלא ניתן ליצור מופעים שלה כלל. תפקידה הוא לאגד מתודות סטטיות (שהן למעשה פונקציות) קשורות בינן לבין עצמן.[23] מחלקות סטטיות מאפשרות לכתוב מתודות-הרחבה (ראה בהמשך) עבור מחלקות אחרות.

מתודות (שיטות)

בשפת C#‎ לא ניתן לכתוב פונקציות גלובליות או להגדיר משתנים גלובליים כמו בשפת C++‎ ו-VB. כל המתודות חייבות להיות מאוגדות במחלקות, ובפרט הפונקציה Main, שהיא נקודת הכניסה (ההתחלה) של התוכנית.

התחליף לפונקציה גלובלית הוא מתודה סטטית (static), המופעלת דרך שם המחלקה שלה בלי הצורך ליצור מופע. כתחליף למשתנה גלובלי ניתן להגדיר משתנה סטטי במחלקה. מתודה סטטית איננה יכולה לגשת למשתנים רגילים ללא התייחסות לאובייקט ספציפי, אך יכולה לגשת למשתנים סטטיים, אותם ניתן לאתחל באמצעות בנאי סטטי. ניתן להגדיר מחלקה כסטטית, ובמחלקה כזאת ניתן להגדיר רק מתודות סטטיות. לדוגמה, המחלקה Console היא סטטית, וכך גם המתודות הכלולות בה כגון WriteLine. סוג מיוחד של מתודות סטטיות הן מתודות-הרחבה (extension methods).[24]

במחלקות אבסטרקטיות ובממשקים ניתן להגדיר "מתודה אבסטרקטית": חתימה של מתודה ללא מימוש, שתמומש על ידי מחלקה יורשת.

ניתן להגדיר מתודה כוירטואלית (virtual) ולאפשר שינוי של המתודה במחלקה הנגזרת באמצעות המילה override.[25] מתודה וירטואלית היא מתודה עבורה קיים מימוש, אך מימוש זה עשוי להיות מוחלף (להידרס) במחלקה יורשת.

ניתן למנוע דריסה של מתודה וירטואלית במחלקה נגזרת על ידי הגדרתה כמתודה חתומה (sealed) במחלקת הבסיס.[26]

C#‎ מאפשרת העמסת מתודות, שהיא האפשרות לכתוב מתודות בעלות שם זהה, וחתימה שונה (רשימת הפרמטרים צריכה להיות שונה בטיפוסי הפרמטרים או במספרם). כמו כן ניתן ליצור מתודה עם מספר לא ידוע של פרמטרים (באמצעות מילת המפתח params והגדרת מערך ברשימת הפרמטרים. (לדוגמה: (public void FunctionName(params String[] str1). גם ניתן ליצור ערכי ברירת מחדל בפרמטרים של מתודה באופן דומה לכתיבה ב- C#‎.

למחלקה בשפה ניתן לכתוב בנאי (Constructor) המופעל כאשר נוצר מופע, והורס (Destructor) המופעל לפני מחיקת המופע. ההורס קורא בעקיפין למתודה מסיימת (Finalize). כברירת מחדל נוצרים בנאי והורס ריקים. ניתן ליצור מספר רב של בנאים באמצעות העמסה. לרוב אין שימוש ל-Finalize, שכן לא ידוע מתי הוא ייקרא על ידי מנגנון איסוף הזבל.

הסתרה וחלוקה למודולים

יחידת ההסתרה ב-#C היא המחלקה (ולא האובייקט). ישנן חמש רמות הרשאה לגישה לשדות המחלקה:

  1. private: מותרת גישה אך ורק מתוך המחלקה הנוכחית.
  2. protected: מותרת גישה מתוך המחלקה הנוכחית ומחלקות יורשות.
  3. public: מותרת גישה מכל מקום.
  4. internal: מותרת גישה מכל מקום בתוך האסמבלי של המחלקה, שהוא הקובץ בשפת-הביניים אותו מריצה סביבת הNET. לאחר שהתוכנית עוברת הידור.
  5. protected internal: מותרת גישה בתוך היישום ומתוך מחלקות יורשות, גם אם הן באסמבלי אחר.

ניתן לפצל קוד במחלקות חלקיות (partial), שהן מחלקות שמוגדרות במספר מקומות (ואף במספר קבצים). דוגמה רווחת לכך הוא פיצול הגדרת פקדי טופס Winform שנוצרים באמצעות המחולל הגרפי לקובץ designer נפרד כדי לשמור על קובץ cs נקי לכתיבת הקוד עצמו.

ניתן ליצור מחלקות מקוננות. מופעים של מחלקה מקוננת נוצרים באופן בלתי תלוי במחלקת האם (כלומר, אין מחלקות מקוננות לא סטטיות, בניגוד למצב בשפת ג'אווה).

מאפיינים (Properties)

מאפיין הוא שיטה מיוחדת הנקראת Accessor (מאפשר גישה) שמתנהגת מבחינה סינטקטית כמשתנה חבר ותפקידה לאפשר גישה לשדות פרטיים.

בדומה למוסכמה השכיחה ב-Java לכנות מתודות שתפקידן השמה ואחזור של ערכים get ו-set בהתאמה ולאחריהן שם התכונה. אומץ רעיון ה"מאפיינים" מ-Visual Basic כדי להקל על השמה ואחזור שדות פרטיים. בתפיסה זו מאפיין מורכב משדה ושיטות הפועלות עליו: האחת קוראת (getter) והאחרת כותבת (setter). כל שנדרש להגדיר הוא הגבלת ההרשאה (Access Modifier) על פי רעיון הכימוס, לקבוע מה יהיה הערך המוחזר ולקבוע את שם המאפיין. מימוש המאפיין מתנהג כפונקציה חברה לכל דבר, כך ניתן לשלוט בערכים המושמים והמאוחזרים בזמן הריצה. בכל פעם שתתבצע גישה למאפיין היא תופנה ל-get וכל פעם שיוצב ערך במאפיין תתבצע הפעלה של set. כמו כן, החל מגרסה 2.0, ניתן לקבוע רמות הרשאה שונות ל-get ול-set (כך, לדוגמה, ניתן לקבוע הרשאת גישה ציבורית לאחזור get ולהגביל את השמת הערך set לפרטית כך רק מחלקות יורשות יוכלו לשנות את השדה - במקרה כזה המחלקה תקרא Immutable דהיינו לא ניתנת לשינוי. או להסיר את ההשמה לחלוטין, במקרה כזה יקרא המאפיין "קריאה בלבד"). מעבר לעובדה שהמאפיינים מהווים רמת הפשטה למשתמש, הם הופכים את השדה לשדה חכם (smart field) שמאפשר לבצע פעולות נוספות בעת השמה או אחזור, כמו בדיקות תקינות ו/או חריגה או לבצע אתחול עצל, שהוא אתחול בזמן שימוש בשדה ולא בזמן יצירת המחלקה, וכן פעולות לוגיות אחרות.

class Student
{
    int _age;
    public int Age
    {
        get { return _age; }
        set { _age = value; }
    }
}

בדוגמה מחלקת Student שבה מאפיין ציבורי בשם Age שכומס משתנה פרטי בשם _age.

  Student student = new Student();
  student.Age = 26;
  Console.Write(student.Age);

והמימוש במחלקה אחרת יראה באופן הבא: ההשמה תשתמש במתודה set, והתצוגה תשתמש במתודה get של המאפיין. בגרסה 3 ומעלה נוספו מספר יכולות חדשות ביניהן היכולת ליצור "מאפיינים אוטומטיים"[27] - אם יש צורך בגישה לחבר פרטי ללא לוגיקה כלשהי (וגם להשאיר מרווח תמרון להוסיף לוגיקה כזו בעתיד), ניתן ליישמו בדרך ישירה וחסכונית כמו בדוגמה הבאה. במקרה זה המהדר מייצר מאחורי הקלעים שדה מגבה שהגישה אליו אפשרית רק דרך המאפיינים, כאילו נכתב הקוד לעיל:

public int Age { get; set; }

למאפיינים ב-C# תפקיד בתכנות ויזואלי. כל המאפיינים של כל פקד, מוצגים בזמן הפיתוח באמצעות גיליון המאפיינים ואף ניתן לשנות את תכונותיהם, באמצעות הממשק הגרפי, כך השינוי ישתקף בטופס באופן מידי כבר בזמן הפיתוח, מבלי שהמתכנת צריך לעשות שימוש בקוד.

אחד החסרונות של מאפיינים הוא ההסתרה (מבחינה תחבירית) של פעולת חישוב. פעולת גישה למשתנה רגיל היא זולה מאוד, מבחינת זמן חישוב, אך פעולת גישה למאפיין עשויה לדרוש חישוב בלתי מוגבל בזיכרון או בזמן; השפה לא מונעת יצירה של לולאה אינסופית בתוך מאפיין. מהסיבה הזאת אין זה מקובל להגדיר מאפיינים המבצעים חישובים מורכבים.

העמסת אופרטורים

C#‎ מאפשרת העמסת אופרטורים - שהיא טכניקה המאפשרת לתת משמעות חדשה לרוב האופרטורים הקיימים בשפה[28], על מנת להקל על הקריאות של התוכנית. את האופרטור "[ ]" מעמיסים בצורה מעט שונה מהאחרים, בעזרת מנגנון הנקרא סדרן - Indexer הדומה בכתיבתו למאפיין:

private int arr = new int[100];     
public int this[int i] 
{
   get { return arr[i]; }
   set { arr[i] = value; }
}

תכנות מונחה אירועים

האירוע בשפה הוא למעשה מאפיין נוסף של המחלקה, ונחשב לחלק מהעצם כמו השדה והשיטה. event (אירוע) הוא טיפוס Delegate המובנה בשפה בעל הרשאות גישה מיוחדות: ניתן לרשום לאירוע פונקציות גם מחוץ למחלקה בה הוא מוגדר, אך הקריאה אליהן מתבצעת רק מתוך המחלקה. ה-Delegate עצמו הוא מחלקה שמכילה רשימה של הפניות לפונקציות, שניתן באמצעותה להזניק פונקציות ממקומות שונים.[29]

ה-event משמש בשפת #C לתמיכה ישירה בתכנות מונחה אירועים. כדי שיהיה אפשר לתקשר ולהעביר הודעות ומידע בין מחלקות שונות, (בעקבות שפת VB). במחלקה המתארחת ניתן ליצור אירועים בחותמות שונות, ולהזניק אותם במקום הרלוונטי במחלקה באמצעות קריאה בשמם, ובמחלקה המארחת ניתן ללכוד אירועים אלו, באמצעות רישום מוקדם של פונקציה מקומית (בעלת חתימה זהה) לאירוע של האובייקט לאחר ההכרזה עליו. התוצאה היא שבעת שאירוע מוזנק במחלקה המתארחת, הוא גורם למעשה להרצת הפונקציה במחלקה המארחת.

בדוגמה מוגדר event מטיפוס MultiplicationEventHandler במחלקה CalculationEvent, לאחר מכן מתבצע במחלקה המארחת HostCalculationEvent יצירת מופע של המחלקה ורישום האירוע MultiplicationEventHandler לפונקציה testCalculation_MultiplicationNum, כך שבעת הזנקה שלו תופעל פונקציה זו.

במחלקה המתארחת : CalculationEvent

class CalculationEvent
{
    public delegate int MultiplicationEventHandler(int x, int y);
    public event MultiplicationEventHandler MultiplicationNum;

    public int RaiseCalc(int x, int y)
    {
        return MultiplicationNum(x, y);
    }
}

במחלקה המארחת: HostCalculationEvent

class HostCalculationEvent
{
    CalculationEvent testCalculation = new CalculationEvent();

    public HostCalculationEvent()
    {
        testCalculation.MultiplicationNum += new CalculationEvent.MultiplicationEventHandler(testCalculation_MultiplicationNum);
    }

    int testCalculation_MultiplicationNum(int x, int y)
    {
        return x * y;
    }
}

תכנות פונקציונלי

נציג (Delegate) הוא טיפוס המובנה בשפה, המגדיר חתימה של פונקציה, וכל מופע שלו מחזיק רשימה של עצמים ברי-קריאה המתאימים לחתימה זאת[30]. קריאה לנציג יוזמת קריאה של כל האובייקטים המוחזקים בו. ניתן לרשום (Subscribe) פונקציות לנציג בעזרת אופרטור =+, ולקרוא להן בעזרת תחביר רגיל של קריאה לפונקציה.

דוגמה לתוכנית "שלום עולם" בעזרת נציגים:

class HelloWorld
{
    public delegate void Del();
    static void Main(string[] args) {
        Del x = delegate { Console.Write("hello "); };
        x += delegate { Console.WriteLine("world"); };
        x();
    }
}

טיפוס בסיסי זה מאפשר להשתמש בטכניקות של תכנות פונקציונלי. למשל הוא מאפשר לקרוא לפונקציה לא מוכרת במחלקה, ליצור אירועים, ולהפעיל תהליכון (Thread)[31].

ישנם מספר מימושים גנריים ל-Delegates בספריה הסטנדרטית של C#‎:

  • Action: פונקציה המקבלת פרמטרים אך לא מחזירה דבר[32].
  • Func: פונקציה המקבלת פרמטרים כלשהם ומחזירה טיפוס כלשהו.
  • Predicate: פונקציה המקבלת פרמטר אחד ומחזירה טיפוס בוליאני.
  • Comparison: פונקציה המקבלת שני פרמטרים בני אותו טיפוס, ומחזירה ערך מספרי. נועדת להשוואה בין אובייקטים[33].

דוגמאות:

Action<> printHello = delegate { Console.Write("hello world!"); };

Predicate<int> range255 = delegate(int x) {return x>=0 && x<=255;};

Func<string, string> convert = delegate(string s) {return s.ToUpper();};

פונקציות אנונימיות וביטויי למבדה

החל מגרסה 2 שפת C# תומכת במתודות אנונימיות - פונקציה הנכתבת בשורת פקודה, ומוגדרת בזמן ההרצה עצמה[34]. החל מגרסה 3 נוספה תמיכה בביטויי למדא לשפה. זוהי דרך נוספת תמציתית וגמישה לכתוב מתודה אנונימית[35]. שימוש בפונקציות אנונימיות נעשה כאשר רוצים להשתמש בפונקציה באופן מקומי מבלי להגדירה במחלקה, או כאשר פרמטר של פונקציה מוגדר כפונקציה, ואז ניתן לכתוב את הפונקציה האנונימית בקריאה לפונקציה, מבלי להגדירה כלל כפונקציה במחלקה.

בדוגמה מימוש של הפונקציה שלעיל באמצעות ביטוי למדא. (האופרטור <= מפעיל הלמדא, מפריד בין הפרמטרים של הקלט בצידו השמאלי לגוף הלמדא מצידו הימני)

 
Func<string, string> Convert = x => x.ToUpper();

בביטויי למדא נעשה שימוש רב ב-LINQ. בדוגמה איתור גודל המילה הקטנה ביותר במערך מחרוזתי מתקבל במשתנה shortestWordLength.

 
string[] wordsArray = {"Orange", "Apple", "Pineapple", "Pear", "Peach"};
int shortestWordLength = wordsArray.Min(w => w.Length);

תכנות גנרי

השפה תומכת בפולימורפיזם פרמטרי: ניתן להגדיר מחלקה המקבלת טיפוסים כפרמטרים:

public class GenericList<T> {
    void Add(T input) { }
}

ניתן להעביר כפרמטר כל טיפוס - פרימיטיבי, טיפוס-ערך או טיפוס-התייחסות:

class TestGenericList {
    private class ExampleClass { }
    static void Main() {
        // Declare a list of type int.
        GenericList<int> list1 = new GenericList<int>();

        // Declare a list of type string.
        GenericList<string> list2 = new GenericList<string>();

        // Declare a list of type ExampleClass.
        GenericList<ExampleClass> list3 = new GenericList<ExampleClass>();
    }
}

ניתן להגדיר אילוצים של טיפוסים באמצעות משפט where, כך למשל ניתן להגדיר שמחלקה מסוימת תהיה רק מטיפוס מחלקה, מבנה או טיפוס קונקרטי. וניתן לתת ערכי ברירת מחדל למשתני הג'נריקס באמצעות המילה default.

מנגנון הג'נריקס ב#C איננו מתבצע בעזרת תבניות בזמן קומפילציה (כמו ב++C) ואיננו נעלם בזמן ריצה (כמו ב-Java) אלא מתבצע בזמן טעינה, וכל אובייקט שומר בתוכו מידע על הפרמטרים בעזרתם הוא נוצר גם בזמן ריצה, על מנת לאפשר ריפלקשן ובטיחות טיפוסים.

ניתן להעביר רק טיפוסים (ולא קבועים מספריים, למשל, כמו ב++C). מטיפוסים אלה ניתן לדרוש דברים מסוימים, כגון ירושה ממחלקה או ממשק מסוים, או קיומו של בנאי נטול פרמטרים.

לא ניתן לבצע ספציאליזציה של מחלקה גנרית עבור טיפוס ספציפי. כתוצאה מכך, כוח החישוב של מנגנון הג'נריקס ב-#C חלש יותר משל התבניות בשפת ++C, והוא איננו מאפשר להגדיר חישובים מורכבים שיתבצעו בזמן הידור או טעינה - הוא איננו שלם-טיורינג; כל תפקידו הוא יצירה של טיפוסים, משתנים, Delegates ופונקציות בעזרת פרמטרים (במילים אחרות: הוא מאפשר תכנות גנרי, אך לא מטא-תכנות). חולשה זו מאפשרת להדר ולטעון קוד גנרי מהר יותר.

תכנות דינמי

על אף שהשפה היא במהותה שפה סטטית, החל מגרסה 4 נוספה לה תמיכה בתכנות דינמי, דהיינו הגדרת האובייקטים כמו משתנים, מאפיינים, שיטות ואירועים בזמן ריצה, ולא בזמן הקומפילציה. לצורך השימוש בתכנות דינמי נוסף טיפוס חדש מסוג dynamic.

בדוגמה הבאה ניתן לראות שטיפוס המשתנה d1 משתנה בעקבות ההשמה של התוכן, ממחרוזת למספר שלם.

    dynamic d1 = "STRING";
    Console.WriteLine(d1.GetType());
    // Prints "System.String".
    d1 = 60;
    Console.WriteLine(d1.GetType());
    // Prints "System.Int32".

ונוספו מחלקות חדשות לטיפול דינמי (באמצעות מרחב System.Dynamic). המחלקה DynamicObject שבאמצעותה ניתן להוסיף ולשנות מאפיינים תוך כדי ריצה, ובאמצעות המחלקה ExpandoObject שנותנת טיפול כולל יותר, ניתן להוסיף למחלקה בזמן ריצה כל אובייקט, מאפיין, שיטה ואף אירוע. מחלקה זו תומכת בלינקיו ובתחשיב למדא. דרך נוספת לתכנות דינמי היא באמצעות יכולת ה-Reflection של הC# (אם כי דרך זו מורכבת יותר למימוש).

בדוגמה הבאה נוצרת באמצעות ExpandoObject מחלקה בזמן ריצה שיש לה שני מאפיינים (בשמות Name מסוג מחרוזת ו-Age מסוג מספרי) ושיטה אחת (בשם Increment) שמוסיפה 5 לערך שקיים במאפיין Age. בסוף הדוגמה יוצג בחלון Output התוכן הבא: Name: John Smith , Age: 20

    using System.Dynamic;
    ...
    dynamic employee = new ExpandoObject() ;
    employee.Name = "John Smith";
    employee.Age = 15;

    employee.Increment = (Action)(() => { employee.Age+=5; });
    employee.Increment();

    Console.WriteLine("Name: " + employee.Name + " " + ", Age: " + employee.Age);

התמיכה מאחרי הקלעים בתכנות הדינמי נעשית באמצעות מהדר אחר ה-DLR ולא הCLR. בשל כך באובייקטים דינמיים לא ניתן להשתמש בתכונת ה-Reflection ולא ב-Intellisense.

תכנות ויזואלי

תמונת מסך של כלי פיתוח לתכנות חזותי ב-WinForm ב-C#, טופס, פקדים, רכיבים, חלונית Toolbox, חלונית מאפיינים, חלונית Document outline.

השפה תומכת בתכנות ויזואלי בעיקר בממשקי משתמש, באמצעות ספריות סטנדרטיות של הדוט נט וכלי פיתוח של הסטודיו, כאשר אלמנטים בשפה כ-Events ו-Properties משתלבים בפיתוח הוויזואלי ומקלים עליו. ניתן ליצור טפסים (Form) ליישומים שולחניים באמצעות ה-Winform, דפים (Page) ליישומי אינטרנט באמצעות ה-WebApplication, חלונות (Window) ליישומי גרפיקה מתקדמים באמצעות מודל התכנות WPF, ומסכים (Screen) ביישומי משחקים.

הקונספט שנלקח מ-VB והורחב והועצם, הוא יצירת אובייקט ראשי המסמל טופס, דף או חלון בהתאם לסוג היישום, שיכול להכיל בתוכו פקדים שהם מודלים תכנותיים קטנים, המיוצגים באמצעות צלמיות, שיכולים לתקשר זה עם זה. על גבי הטופס ניתן ל"צייר" ולמקם פקדים באמצעות גרירתם מחלונית "ארגז כלים" (ToolBox), וניתן לראות את צורת הסידור שלהם באמצעות חלונית "מתאר מסמך" (Document outline/Designer). ישנה חלוקה פנימית בין פקדים (Controls) (שהם רכיבי תוכנה ויזואליים כמו פקד תיבת טקסט ופקד תמונה) לבין רכיבים (Components) (שהם רכיבי תוכנה לוגיים, למשל רכיב FileSystemWatcher שעוקב אחר שינויים בקבצים, או רכיב BackgroundWorker שמאפשר ליצור תהליכון נפרד עם אירועים). הקשר בין פעולות הממשק לקוד הוא דו כיווני: לכל פעולה ויזואלית מחולל קוד מתאים, למשל גרירה של פקד אל הטופס יוצרת הכרזה שלו בטופס ואתחול של מאפיינים מסוימים שנקבעו מראש, כמיקום הפקד בטופס, וגודלו, וכל שינוי בקוד מתורגם לייצוגים הוויזואליים בחזרה.

ב-WebApplication קיימים כ-90 פקדים ורכיבים שונים, וב-Winform קיימים כ-70 פקדים ורכיבים שונים. ניתן ליצור פקדי ורכיבי משתמש מותאמים אישית על בסיס פקדים ורכיבים קיימים, או פקדים ורכיבים חדשים. הפקדים מסווגים בדרך כלל לכמה קטגוריות עיקריות. ב-Winform למשל הם מסווגים לשיתופיים, מכולות (פקדים שמכילים פקדים אחרים), תפריטים, נתונים (לעבודה עם בסיסי נתונים), תיבות שיח ועוד. דרך העבודה האופיינית היא גישה אל הקוד מתוך הממשק והליכה מהכלל אל הפרט. תחילה יש ליצור את הטופס, לשרטט עליו את הפקדים, ולאחר מכן להגדיר את מאפייניהם השונים, והאירועים הדרושים ליישום באמצעות חלונית "מאפיינים" (Properties) שמציגה את המאפיינים והאירועים הקיימים בפקד, ואז ליצור אירוע באזור הקוד, ולכתוב בו את הקוד הנדרש כדי לממש את התוכנית.

זיכרון מנוהל

במטרה למנוע בעיות הנובעות מניהול עצמאי של זיכרון כמו זליגת זיכרון ודריסת זיכרון, שפת C#‎, כחלק מטכנולוגיית NET., מוגדרת כ"קוד מנוהל" (Managed Code). המתכנת פטור מן האחריות לשחרור מפורש של זיכרון המוקצה לאובייקט. סביבת ההרצה (CLR - Common Language Runtime) היא המופקדת על שחרור הזיכרון שתופסים עצמים שאינם בשימוש יותר.

לצורך כך, יוזמת סביבת ההרצה אחת לזמן מה תהליך של "איסוף זבל" (Garbage collection), הממפה את כל העצמים במערכת ומסמן למחיקה את אלו שאינם בשימוש. לצורך המיפוי מוגדרים מספר רכיבים ראשיים ("שורשים"). עצם הוא בשימוש אם הוא מוחזק על ידי אחד הרכיבים הראשיים, או שניתן להגיע אליו מאחד הרכיבים הראשיים דרך סדרה של עצמים אחרים. עצמים שאינם בשימוש מסומנים למחיקה. אם הוגדר עליהם קוד הרצה לפני מחיקה (Finalizer) הוא יבוצע. ולאחר מכן העצם ימחק והזיכרון אותו תפס ישוחרר.

זיכרון מנוהל אמור להבטיח ניצול של משאבי הזיכרון, אך הוא אינו מגן על משאבים אחרים כדוגמת גישה לבסיסי מידע, קבצים פתוחים וכדומה. בנוסף, זליגת זיכרון עדיין עלולה לקרות אם כתוצאה משגיאה בתוכנית ניתן לגשת אל עצמים גם כאשר אין בהם עוד צורך. מנגנון איסוף הזבל לא יכול לדעת שמדובר בשגיאה, ולא יפנה את העצמים מן הזיכרון.

טיפול בחריגות

C#‎ תומכת בטיפול בחריגות (מנגנון בקרת זרימה המיועד לציין ולטפל במצבים לא תקינים במהלך הריצה של התוכנית) על ידי "זריקת" אובייקטים במעלה שרשרת הקריאות לפונקציה, כדי להעביר מידע על החריגה. אפשר לזרוק רק אובייקטים ממחלקות היורשות מהמחלקה Exception. אין דרך להצהיר על החריגות הנזרקות ממתודה, חריגה שנזרקת ולא נתפסת תפעפע עד סביבת הריצה עצמה.

תאימות לאחור

כדי להקל על מפתחים להגר משפות אחרות[דרוש מקור], ובפרט משפת C++‎, אל שפת C#‎, נכללו בשפה "כינויים" למספר מחלקות ומבנים, הזהים לשמות המקבילים בשפת C++‎:

מחלקה כינוי תיאור גודל בבתים איתחול אוטומטי
System.Byte byte בית 1 0
System.Int16 short שלם קצר 2 0
System.Int32 int שלם 4 0
System.Int64 long שלם ארוך 8 0
System.Decimal decimal שלם דצימלי 12 0
System.Single float ממשי 4 0.0
System.Double double ממשי כפול 8 0.0
System.Boolean bool בוליאני 1 false
System.Char char תו יוניקוד בודד 2 /0
System.String string מחרוזת יוניקוד null

בנוסף, קיימים כינויים למחלקות שאינן קיימות כסוגי משתנים בשפת C++‎: הכינוי object למחלקה Object, וכן הקידומת unsigned משפת C++‎ תהיה בדרך כלל הקידומת u לכינוי המתאים (למעט byte, שהוא כבר unsigned, ולכן קיים הכינוי sbyte, שהוא byte עם סימן). למשל, unsigned int בשפת C++‎ מקביל ל-uint בשפת C#‎, שאינו אלא כינוי למבנה UInt32.

המבנה Char בשפת C#‎ מכיל נתון באורך 16 סיביות או יותר (קידוד UTF-16), כדי שיוכל להכיל תו יוניקוד, בניגוד ל-char של C++‎ שהוא על פי רוב באורך 8 סיביות (מתאים להכיל תו ASCII, או בית בודד).

ניתן להשתמש בכינוי של מחלקה או בשם המפורש שלה, ללא כל משמעות מבחינת ריצת התוכנית.

גרסאות

ל-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
C# 6.0 יולי 2015 ‎.NET Framework 4.6 Visual Studio 2015


תקציר הגרסאות
C# 2.0 C# 3.0 C# 4.0 C# 5.0 C# 6.0
תכונות
שהוספו
  • ג'נריקס
  • טיפוסים חלקיים (Partial)
  • מחלקה סטטית
  • מתודות אנונימיות
  • איטרטורים
  • טיפוסים מאפשרים ערכי NULL
  • הגדרת מאפיין (setters) כפרטי
  • Method group conversions (delegates)
  • טיפוס מרומז של משתנים מקומיים (var)
  • מאתחל אובייקטים ואוספים
  • מימוש אוטומטי של מאפיינים
  • טיפוסים אנונימיים
  • מתודות הרחבה
  • ביטויי שאילתה
  • ביטויי למדא
  • עצי ביטויי
  • מתודות חלקיות
  • LINQ
  • כריכה דינמית
  • טיפוס דינמי (Dynamic)
  • ארגומנטים אופציונלים
  • Generic co- and contravariance
  • Embedded interop types ("NoPIA")
  • מתודות אסינכרוניות (Async / await)
  • Caller info attributes
  • הידור כשירות (service)
  • יבוא של טיפוסים סטטיים למרחב שם
  • מסנן לחריגות
  • אתחול אוטומטי של מאפיין לקריאה בלבד
  • אתחול של מילון
  • Await בבלוק של catch/finally
  • אינטרפולציה על מחרוזת
  • אופרטור nameof

דוגמה לתוכנית Hello world

להלן דוגמה לתוכנית Hello world בשפה זו[36]:

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

קישורים חיצוניים

הערות שוליים


שגיאות פרמטריות בתבנית:הערות שוליים

פרמטרים [ טורים ] לא מופיעים בהגדרת התבנית

  1. ^ Kovacs, James (7 בספטמבר 2007). "C#/.NET History Lesson". נבדק ב-18 ביוני 2009. {{cite web}}: (עזרה)
  2. ^ C# and Java: Comparing Programming Languages, Msdn
  3. ^ http://news.cnet.com/2008-1082-817522.html
  4. ^ "C# משלבת את היצרנות הגבוהה של Microsoft Visual Basic עם העוצמה הגלומה ב-C++" סקוט וויילטמוף (חבר בצוות הפיתוח של השפה) מצוטט ב-C# למתכנתי Java/C++/Visual C++, הוצאת מיקרוסופט והוד עמי, ישראל 2002, עמ' 14
  5. ^ http://msdn.microsoft.com/en-us/library/vstudio/ms233843.aspx
  6. ^ http://msdn.microsoft.com/en-us/library/vstudio/dd264741.aspx
  7. ^ http://msdn.microsoft.com/en-us/library/vstudio/chfa2zb8.aspx
  8. ^ http://msdn.microsoft.com/en-us/library/vstudio/bb383973.aspx
  9. ^ http://msdn.microsoft.com/en-us/library/vstudio/bb397687.aspx
  10. ^ http://msdn.microsoft.com/en-us/library/vstudio/ms173109.aspx
  11. ^ http://msdn.microsoft.com/en-us/library/vstudio/490f96s2.aspx
  12. ^ http://msdn.microsoft.com/en-us/library/vstudio/s1ax56ch.aspx
  13. ^ http://msdn.microsoft.com/en-us/library/vstudio/yz2be5wk(v=vs.120).aspx
  14. ^ "In general, classes are used to model more complex behavior, or data that is intended to be modified after a class object is created. Structs are best suited for small data structures that contain primarily data that is not intended to be modified after the struct is created.", [מקור http://msdn.microsoft.com/en-us/library/vstudio/ms173109.aspx]
  15. ^ http://msdn.microsoft.com/en-us/library/vstudio/8f1hz171.aspx
  16. ^ http://msdn.microsoft.com/en-us/library/vstudio/14akc2c7.aspx
  17. ^ http://msdn.microsoft.com/en-us/library/vstudio/ee332485.aspx
  18. ^ http://msdn.microsoft.com/en-us/library/vstudio/w5zay9db.aspx
  19. ^ http://msdn.microsoft.com/en-us/library/vstudio/e6w8fe1b.aspx
  20. ^ http://msdn.microsoft.com/en-us/library/vstudio/acdd6hb7.aspx
  21. ^ http://msdn.microsoft.com/en-us/library/vstudio/ms173150.aspx
  22. ^ http://msdn.microsoft.com/en-us/library/88c54tsw.aspx
  23. ^ http://msdn.microsoft.com/en-us/library/vstudio/79b3xss3.aspx
  24. ^ http://msdn.microsoft.com/en-us/library/vstudio/bb383977.aspx
  25. ^ http://msdn.microsoft.com/en-us/library/ebca9ah3.aspx
  26. ^ http://msdn.microsoft.com/en-us/library/88c54tsw.aspx
  27. ^ http://msdn.microsoft.com/en-us/library/bb384054.aspx
  28. ^ http://msdn.microsoft.com/en-us/library/vstudio/8edha89s(v=vs.120).aspx
  29. ^ http://msdn.microsoft.com/en-us/library/vstudio/8627sbea.aspx
  30. ^ http://msdn.microsoft.com/en-us/library/vstudio/ms173172.aspx
  31. ^ ThreadStart Delegate
  32. ^ http://msdn.microsoft.com/en-us/library/018hxwa8.aspx
  33. ^ http://msdn.microsoft.com/en-us/library/tfakywbh.aspx
  34. ^ http://msdn.microsoft.com/en-us/library/vstudio/0yw3tz5k.aspx
  35. ^ http://msdn.microsoft.com/en-us/library/vstudio/bb397687.aspx
  36. ^ על מנת שהתוכנית תמתין לתגובה מהמשתמש, יש להוסיף את הפקודה ()Console.Read לאחר השורה השלישית מהסוף.