سی‌شارپ

سی‌شارپ  زبانی شیءگرا و سطح بالا از خانوادهٔ زبان‌های چارچوب دات‌نت شرکت مایکروسافت است.

زبان سی‌شارپ، یک زبان برنامه‌نویسی چند الگویی و منظم شده مدل‌های تابعی، امری، عمومی، شیءگرا و جز گرا و در بستر دات نت می‌باشد. این زبان توسط مایکروسافت و جزئی از دات نت به وجود آمد و بعداً استانداردهای ECMA و ISO را نیز دربر گرفت. سی‌شارپ یکی از ۴۴ زبان برنامه‌نویسی است که توسط زمان اجرای زبان مشترک از چارچوب دات‌نت پشتیبانی و در همه جا به وسیله مایکروسافت ویژوال استودیو شناخته می‌شود.

زبان سی‌شارپ با قدرت و در عین حال سطح بالای خود توانسته توجه بسیاری از برنامه نویسان را به خود جلب کند.

این زبان برپایه سادگی، مدرن بودن، همه منظوره و شیءگرا بودن ساخته شد. آندرس هجلزبرگ، طراح زبان برنامه‌نویسی دلفی، سرپرستی تیم طراحان زبان سی‌شارپ را بر عهده داشت. این زبان دارای دستوری شیءگرا مشابه ++C است و به شدت از زبان‌های جاوا و دلفی تأثیر پذیرفته است. در ابتدا نام این زبان COOL بود که مخفف C like Object Oriented Language بود، هر چند در ژوئیه ۲۰۰۰، زمانی که مایکروسافت پروژه را عمومی اعلام کرد، اسم آن به سی‌شارپ تغییر پیدا کرد.

 اهداف طراحی زبان سی‌شارپ 
استاندارد ECMA این اهداف طراحی زبان را برای سی‌شارپ برآورده می‌سازد:
 سی‌شارپ یک زبان برنامه‌سازی ساده، مدرن و نوآور برای اهداف عمومی و شیءگرا است.
 به دلیل اهمیت داشتن موضوع نیرومندی و دوام و بهره‌وری برنامه‌نویس، زبان دارای چک‌کننده Strong Type، چک‌کننده مرزهای آرایه، تشخیص حالت‌هایی که یک متغیر مقداردهی اولیه نشده است، قابلیت انتقال کدها و بازیافت حافظه خودکار است.
 این زبان برای استفاده در اجزای توسعه نرم‌افزار برای دستیابی به مزایای سامانه‌های توزیعی در نظر گرفته شده است.
 قابلیت انتقال برنامه‌نویس بسیار مهم است، خصوصاً برای آن دسته از برنامه‌نویسانی که با زبان‌های C و C++ آشنا هستند.
 پشتیبانی از این زبان برای بین‌المللی شدن بسیار مهم است.
 زبان سی‌شارپ برای نوشتن برنامه‌ها برای سامانه‌های تعبیه شده و میزبان در نظر گرفته شده است، سیستم عامل‌های پیچیده بسیار بزرگ گرفته تا توابع اختصاصی بسیار کوچک.
 هر چند برنامه‌های نوشته شده با سی‌شارپ طوری هستند که از لحاظ حافظه و پردازنده مورد نیاز مقرون به صرفه باشند، ولی خود زبان از لحاظ اندازه و کارایی به خوبی زبان‌های C و اسمبلی نیست.
 در هر نرم‌افزاری که بتوان کدهای سی‌شارپ را وارد کرد بخشی وجود دارد که برای افراد مبتدی در برنامه‌نویسی است این بخش console.aplication نام دارد

 تاریخچه 
در سال ۱۹۹۹، شرکت سان اجازه استفاده از زبان برنامه‌نویسی جاوا را در اختیار مایکروسافت قرار داد تا در سیستم‌عامل خود از آن استفاده کند. جاوا در اصل به هیچ پلت فرم یا سیستم‌عاملی وابسته نبود، ولی مایکروسافت برخی از مفاد قرار داد را زیر پا گذاشت و قابلیت مستقل از سیستم‌عامل بودن جاوا را از آن برداشت. شرکت سان پرونده‌ای علیه مایکروسافت درست کرد و مایکروسافت مجبور شد تا زبان شیءگرای جدیدی با کامپایل جدید که به ++C شبیه بود را درست کند.
در طول ساخت دات نت، کلاس‌های کتابخانه‌ای با زبان و کامپایلر SMC نوشته شدند. در سال ۱۹۹۹ آندرس هلزبرگ گروهی را برای طراحی زبانی جدید تشکیل داد که در آن زمان نامش COOL بود و همانند C بود با خواص شیءگرایی. مایکروسافت در نظر داشت اسم این زبان را تا آخر Cool قرار دهد، ولی به دلیل مناسب نبودن برای اهداف تجاری این کار را نکرد.
در ارائه و معرفی رسمی چارچوب دات‌نت در PDC در سال ۲۰۰۰ این زبان به سی‌شارپ تغییر نام یافت و کتابخانه کلاس‌ها و runtime در ای‌اس‌پی‌دات‌نت به سی‌شارپ منتقل شدند.
مدیر و سرپرست طراحان در مایکروسافت آندرس هلزبرگ بود که تجربه قبلی او در طراحی Framework و زبان‌های برنامه سازی++Borland، دلفی، Turbo Pascal، ویژوال سی++ به آسانی در دستورالعمل‌های سی‌شارپ قابل رویت است و به همان خوبی در هسته CLR.

 ویژگی‌ها 
برخی از تفاوت‌های زبان سی‌شارپ با C و ++C عبارتند از:
 هیچ تابع یا متغیر سراسری (Global) وجود ندارد، تمام متدها و اعضا بایستی در داخل کلاس‌ها تعریف شوند. این امر ممکن است، هر چند برای استفاده از متغیرها و توابع عمومی باید از متدها و متغیرها در کلاس‌های عمومی استفاده کرد.
 متغیرهای عمومی، برخلاف C و ++C، نمی‌توانند بلاک‌های پیوستی را در بر بگیرند.
 سی‌شارپ دارای یک نوع داده بولی است (bool). برخی از عبارت‌ها مانند while و if که شرطی هستند، نیازمند یک عبارت نوع بولی هستند. همان‌طور که ++C نیز دارای نوع داده بولی است، این نوع داده به راحتی می‌تواند به یا از Integerها تبدیل شود، و عبارتی مانند (if(a نیازمند این امر است که a از یک نوع قابل تبدیل به bool یا اشاره گر باشد. کامپایلر سی‌شارپ برنامه‌نویس را در این شرایط مجبور به استفاده از عباراتی می‌کند که به درستی یک مقدار bool را برمی‌گردانند؛ بنابراین دستوری مانند (if(a = b باعث بروز خطا می‌شوند. (به جای = بایستی از == استفاده شود)
 در سی‌شارپ، اشاره گرهای به حافظه بایستی فقط در داخل بلوکهای unsafe استفاده شوند و برنامه در این حالت برای اجرا نیاز به اجازه از کاربر دارد. بیشتر دسترسی شی از طریق شی امن است که یا همیشه در حال اشاره به شی صحیح موجود است یا یک مقدار Null دارد. اشاره گری به شی به درد نخور یا بلاک حافظه رندم غیرممکن است. اشاره گر نا امن می‌تواند به نمونه‌ای از value-type، آرایه، رشته یا بلاکی که حافظه به آن داده شده است اشاره نماید. کدی که به عنوان نا امن علامت نخورده باشد، هنوز می‌تواند اشاره گرها را از سامانه بازیابی یا در آن ذخیره کند ولی نمی‌تواند مرجع جدیدی به آنها اختصاص دهد.
 حافظه ساماندهی شده نمی‌تواند صریحاً آزاد شود، ولی به‌طور خودکار به عنوان به درد نخور تلقی می‌شود. انتخاب آدرس‌های به درد نخور حافظه نفوذ ناپذیر است. هم چنین سی‌شارپ با استفاده از عبارات، پشتیبانی مستقیمی از پایان اجباری می‌کند (پشتیبانی از اصطلاح Resource Acquisition Is Initialization).
 وراثت چندگانه از کلاس‌ها در این زبان پشتیبانی نمی‌شود. البته یک کلاس امکان ارث بری از تعداد نامحدود واسط‌ها را دارد. پشتیبانی نکردن از وراثت چندگانه به دلیل اهداف معماری این زبان در CLI و برای جلوگیری از پیچیدگی است. در عوض می‌توان از اینترفیس‌های مختلف استفاده کرد؛ یعنی برای یک کلاس که احتمالاً فرزند کلاسی دیگر است (ارث برده) می‌توان چندین اینترفیس را پیاده‌سازی (Implement) نمود.
 سی‌شارپ بسیار typesafe تر از C++ است. تنها تبدیلات ضمنی مثل تبدیل نوع داده کوچکتر به بزرگتر یا تبدیل نوع مشتق شده به نوع پایه به‌طور پیش فرض و بدون خطا صورت می‌پذیرد. هیچ تبدیل ضمنی ای میان Booleanها و Integerها وجود ندارد و هر تبدیل user-defined بایستی به صراحت با یکی از کلمات explicit یا implicit نشانه گذاری شود. تبدیل b به a در حالتی که a یک Integer و b یک double باشد در زبان C++ مجاز است اما در سی‌شارپ به یک خطای زمان کامپایل منجر می‌شود (بایستی به صورت explicit تعریف شود)
 سی‌شارپ بستری امن و قدرتمند برای ساخت نرم‌افزارهای hybrid را مهیا می‌کند.
 اعضای Enumeration در داخل محدوده شخصی خود قرار دارند.
 سی‌شارپ قابلیت syntactic sugar را برای توابع متداول، اکسسورها و ماجول‌های کسول شده در یک کلاس به صورت ویژگی‌ها قرار داده است.
اکسسورها که خاصیت نیز گفته می‌شوند در زبان سی‌شارپ قادر به کنترل دسترسی اعضا و معتبرسازی داده‌ها هستند.
 تمام انواع بازتابی (Reflection) و بازیابی (Recovery) قابل استفاده است.
 در حال حاضر (۳ ژوئن ۲۰۰۸) دارای ۷۷ کلمه رزرو شده است.
این زبان جزو زبان‌های خانواده c می‌باشد و شباهت سینتکسی با زبان جاوا دارد.

 ساختمان داده (ساختار و ذخیره‌سازی داده) 
این کامپایلر در مقابل C یا ++C دارای ساختار بسیار متفاوتی است که دانستن آن به برنامه‌نویس امکان نوشتن برنامه‌های بسیار بهینه را خواهد
داد.

 رشته‌ها 
در C یا ++C ساختار رشته به صورت ارایه‌ای از نوع char بود که امکان اضافه کردن به رشته را محدود می‌کرد به دلیل ثابت بودن طول در آغاز تعریف
ولی در سی‌شارپ دو نوع متفاوت رشته وجود دارد؛ که یکی به صورت ارایه‌ای با طول ثابت ۲۵۶(در عمل ۲۵۵)موجوداست (به صورت پیش فرض)
و در صورتی که با کمبود جا روبرو شود فضای جدید (بزرگتر) یافته و به ان انتقال می‌دهد؛ ولی در نوع دوم رشته‌ها از لیست پیوندی استفاده می‌شود.

 سامانه یکپارچه شده 
سی‌شارپ دارای یک سامانه نوع یکپارچه است که به آن CTS می‌گویند. این بدان معناست که تمام انواع، شامل موارد اصلی مانند Integerها، مشتق شده از System.Object هستند. به عنوان مثال، هر نوع یک متد به نام ToString() را به ارث می‌برد. بخاطر کارایی، انواع اولیه (و انواع مقداری) به‌طور داخلی فضایی برای آنها بر روی پشته در نظر گرفته می‌شود.

 انواع داده 
CTS داده‌ها را به دو نوع تقسیم می‌کند:
 نوع مقداری (Value Type)
 نوع ارجاعی (Refrence Type)
انواع داده‌ای توده ساده‌ای از داده می‌باشند. نمونه‌های انواع داده‌ای نه هویت مرجعی دارند و نه مفاهیم مقایسه مراجع را. برای مقایسه برابری یا عدم برابری انواع داده‌ای، خود مقدار داده‌ها را با یکدیگر مقایسه می‌کنیم مگر اینکه عملگرهای مشابه دوباره تعریف شده باشند. مقادیر داده‌های مرجعی همیشه یک مقدار پیش فرض دارند و همیشه می‌توانند ایجاد یا کپی شوند. یکی دیگر از محدودیت‌های انواع داده‌ای این است که آنها نمی‌توانند از یکدیگر مشتق شوند (ولی می‌توانند اشتراکاتی داشته باشند) و هم چنین نمی‌توانند در سازنده مقدار دهی اولیه شوند. مثالی از انواع داده‌ای، بعضی از انواع اولیه مانند int و float و char و System.DateTime می‌باشند.
در مقابل، انواع مرجعی مفهوم تعریف مرجعی را دارند (که در آن هر نمونه از نوع مرجع، به‌طور ذاتی از دیگر نمونه‌ها جدا می‌شود، حتی اگر داده هر دو نمونه یکی باشد). این دقیقاً نمونه مشابه مقایسه تساوی یا عدم تساوی داده‌های مرجعی است، که در آن آزمایش برای مرجع‌ها از داده‌ای‌ها سریع تر است. در کل نه همیشه امکان تعریف نمونه مرجعی وجود دارد و نه امکان کپی یا نمایش مقادیر مقایسه دو نمونه؛ ولی به هر حال انواع مرجعی خاص می‌توانند این اعمال را از طریق سازنده‌های عمومی یا اجرای واسط‌های مشابه (مثل ICloneable یا IComparable) انجام دهند. نمونه‌هایی از انواع مرجعی، اشیاء، System.String و Sysmet.Array می‌باشند.
هر دو نوع داده قابلیت انعطاف توسط تعریف به وسیله کاربر را دارند.
در واقع وقتی ما نوع داده‌ای را به تابع ای ارسال می‌کنیم، آدرس داده نیز فرستاده می‌شود. البته این امر پیش فرض است ولی برای داده‌های مثل آرایه، رشته‌ای، آدرس فرستاده می‌شود و ارسال از نوع مرجع می‌شود.

 نوع‌های پایه (Primitive Types) در زبان C# 
در زبان C#، مجموعه‌ای از نوع‌های داده‌ای پایه (یا Primitive) برای نگهداری و پردازش مقادیر عددی، متنی و منطقی وجود دارد. این نوع‌ها در فضای نام System تعریف شده‌اند و با کلمات کلیدی خاصی در زبان C# قابل دسترسی هستند. هر نوع دارای یک نام رسمی مانند System.Int32 و یک نام مستعار مانند int است که در برنامه‌نویسی رایج‌تر استفاده می‌شود.

 اعداد صحیح (Integer) 
برای نمایش اعداد صحیح، C# چندین نوع مختلف را ارائه می‌دهد که در دو دسته دارای علامت (signed) و بدون علامت (unsigned) قرار می‌گیرند. نوع‌هایی مانند int, short, long برای نمایش اعداد منفی و مثبت مناسب هستند، درحالی‌که نوع‌هایی مانند byte, ushort, uint, ulong فقط اعداد مثبت را نگهداری می‌کنند.

برای مثال:int population = 1_000_000;
byte level = 200;
long stars = 9_000_000_000;نوع int متداول‌ترین نوع برای اعداد صحیح است و بازه‌ای میان حدود ۲ میلیارد منفی تا ۲ میلیارد مثبت را پوشش می‌دهد.

 نمایش اعداد در مبنای ۲ و ۱۶ 
در C# می‌توان اعداد صحیح را به شکل باینری (مبنای ۲) یا هگزادسیمال (مبنای ۱۶) نیز نوشت. برای نمایش باینری از پیشوند 0b و برای هگزادسیمال از 0x استفاده می‌شود:int bin = 0b11111111; // معادل 255
int hex = 0xFF;       // معادل 255همچنین برای خوانایی بهتر، می‌توان از علامت _ بین ارقام استفاده کرد:int billion = 1_000_000_000;

 کنترل سرریز (Overflow) 
اگر جمع یا ضرب عددی از محدوده‌ی نوع داده خارج شود، به‌صورت پیش‌فرض مقدار نهایی wrap می‌شود (سرریز). برای شناسایی این وضعیت، می‌توان از کلمه‌ی کلیدی checked استفاده کرد تا در صورت سرریز، خطای زمان اجرا رخ دهد:int x = 2_000_000_000;
int y = 1_000_000_000;
int z = checked(x + y); // خطای سرریز در زمان اجرابرای غیرفعال کردن این بررسی (مثلاً در بخش خاصی از کد)، می‌توان از unchecked استفاده کرد.

 اعداد اعشاری (Floating-point) 
C# سه نوع داده برای اعداد اعشاری ارائه می‌دهد:

 float: دقت ۳۲ بیتی، سریع اما با خطای تقریب بالا
 double: دقت ۶۴ بیتی، پیش‌فرض برای لیترال‌های اعشاری
 decimal: دقت ۱۲۸ بیتی، بسیار دقیق و مناسب برای محاسبات مالی

نمونه‌ای از استفاده:float piF = 3.14f;
double piD = 3.14;
decimal price = 199.99m;توجه: برای float باید از پسوند f و برای decimal از m استفاده کرد.

 Boxing و UnBoxing 
Boxing عمل تبدیل مقدار نوع داده‌ای به نوع مرجع مشابه آن می‌باشد.

مثال:

int foo = 42;// Value type...
object bar = foo;// foo is boxed to bar.
UnBoxing عمل تبدیل نوع مرجع به نوع داده‌ای می‌باشد.
مثال:

int foo = 42;// Value type.
object bar = foo;// foo is boxed to bar.
int foo2 = (int)bar;// Unboxed back to value type.

سی‌شارپ به برنامه‌نویس با استفاده از کلمه کلیدی Struct اجازه می‌دهد تا انواع مقداری User-defined را ایجاد کند. از دیدگاه برنامه‌نویسی، آنها کلاس‌های سبک‌وزن به نظر می‌رسند. برخلاف کلاس‌ها (که بر روی heap قرار می‌گیرند) و شبیه به انواع اولیه استاندارد مانند انواع مقداری Structها نیز بر روی پشته قرار می‌گیرند. آنها همچنین می‌توانند قسمتی از یک شیء باشند، یا در یک آرایه مرتب شوند، بدون حافظه غیر مستقیمی که به‌طور معمول برای انواع کلاس تخصیص می‌یابد.

 ویژگی‌های جدید در سی‌شارپ ۲٫۰ 
ویژگی‌های جدید در سی‌شارپ چارچوب دات‌نت SDK ۲٫۰ (مطابق با سومین ویرایش استاندارد ECMA-۳۳۴):

 کلاسهای partial 
کلاس‌های Partial اجازه اجرای کلاس‌ها از بیش از یک سورس فایل را می‌دهند. این امر اجازه می‌دهد تا کلاس‌های بسیار بزرگ را قطعه قطعه کنیم و همچنین برای زمانی که برخی قسمت‌های یک کلاس به‌طور خودکار تولید می‌شوند مفید است.

file1.cs:

public partial class MyClass
{
    public MyClass()
    {
// implementation
    }
}

file2.cs:

public partial class MyClass
{
    public void SomeMethod()
    {
// implementation
    }
}

 Genericها 
genericها یا نوع‌های پارامتری شده یا چندریختی‌های پارامتری یک ویژگی جدید چارچوب دات‌نت ۲٫۰ است که به وسیله سی‌شارپ پشتیبانی می‌شود. برخلاف Templateهای سی پلاس پلاس، در این انواع به جای اینکه نمونه سازی توسط کامپایلر انجام شود، در زمان اجرا صورت می‌گیرد، بنابراین می‌توانند چند زبانه باشند در حالی که ++C نمی‌تواند. آنها دارای ویژگی‌هایی هستند که به‌طور مستقیم توسط Templateهای C++ پشتیبانی نمی‌شوند مانند نوع محدودیت‌ها در پارامترهای Generic با استفاده از رابط‌ها(Interface). سی‌شارپ از پارامترهای‌های Generic بدون نوع پشتیبانی نمی‌کند. برخلاف genericهای جاوا،genericهای دات نت برای پارامتری کردن انواع داده‌ای در اشیاء ماشین مجازی CLI، از مفاهیم شی گرایی استفاده می‌کنند که اجازه بهینه‌سازی و حفاظت انواع اطلاعات را می‌دهد.

 کلاس‌های static 
کلاس‌ها به صورت Static قابل تعریف نیستند مگر اینکه تمام اعضای آنها Static باشند؛ که این امر بسیار شبیه به مفهوم مدل در زبانهای رویه‌ای است. (زبان رویه‌ای: یک زبان برنامه‌نویسی که در آن عنصر اصلی برنامه‌نویسی یک زیربرنامه است. مانند زبانهای C، پاسکال و…)

 پرونده:Imag|بندانگشتی|وسط|slam 
 یک شکل جدید از تکرار کننده با استفاده از سازنده توابع 
یک شکل جدید از iterator(تکرار کننده)، با استفاده از ساختار yield return بسیار شبیه به yield زبان پایتون .

// Method that takes an iterable input (possibly an array) and returns all even numbers.
public static IEnumerable<int> GetEven(IEnumerable<int> numbers)
{
    foreach (int i in numbers)
    {
        if (i % 2 == 0) yield return i;
    }
}

 Delegateهای ناشناس 
Delegate یک شی می‌باشد که حاوی یک یا چند اشاره گر به توابع می‌باشد؛ که با Invoke کردن آن تمامی توابع اشاره شده داخل آن اجرا می‌شوند.

Delegateهای ناشناس که عملکردهای محدودی را در سی‌شارپ به وجود می‌آورند. کد کنار بدنه Deletage ناشناس، دسترسی کامل برای خواندن یا نوشتن در متغیرهای عمومی، پارامترهای توابع و اعضای کلاسهای دارای محدوده Deletage را دارد ولی پارامترهای out و ref را پشتیبانی نمی‌کند.
برای مثال:

int SumOfArrayElements(int[] array)
{
     int sum = 0;
    Array.ForEach(       array,
        delegate(int x)
        {
            sum += x;
        }
  );
    return sum;
}

 Delegate covariance and contravariance 
تبدیل گروه‌های متد به نوع Deletage در برگشت دارای covariant و در انواع پارامترها دارای contravariant هستند.

 اکسسورهای یک خاصیت(get و set) می‌توانند دارای سطح دسترسی متفاوتی باشند 
مثال:
 string status = string.Empty;

public string Status
{
    get { return status; }// anyone can get value of this property,
    protected set { status = value; }// but only derived classes can change it
}

نکته مهم: سطح دسترسی خاصیت نمی‌تواند بالاتر از سطح دسترسی اکسسورها باشد. به عنوان مثال private بودن خاصیت و public بودن اکسسور باعث بروز خطا می‌شود.

 نوع داده Nullable 
نوع داده Nullable (که با یک علامت سؤال قابل تشخیص است: int? i = null;)اجازه تخصیص مقدار null را برای انواع داده‌ای می‌دهد. این امر باعث بهبودی فعل و انفعال با پایگاه داده SQL می‌شود. در این حالت نوع ستونی INTEGER NULL در SQL به‌طور مستقیم به int? در سی‌شارپ تبدیل می‌شود.

داده‌های Nullable در آخرین لحظات اوت ۲۰۰۵ اضافه شدند چند هفته مانده به اتمام کار اداری و برای بهبود زبان. متغیر Null در حقیقت خالی نیست، بلکه نمونه‌ای است از struct Nullable<T> با ویژگی HasValue مساوی false. وقتی در برنامه قرار می‌گیرد، خود به خود نمونه خالی در آن قرار می‌گیرد، نه مقدار خود آن، در نتیجه اشاره گر مقصد همیشه غیر Null می‌باشد، حتی برای مقادیر Null. کد زیر نضص بالا را مشخص می‌کند:

int? i = null;
object o = i;
if (o == null)
    Console.WriteLine("Correct behaviour - runtime version from September 2005 or later");
else
    Console.WriteLine("Incorrect behaviour - pre-release runtime (from before September 2005)»);

وقتی درون شی ای کپی می‌شود، نمونه Nullable به صورت تشریفاتی در آن قرار می‌گیرد و در نتیجه مقادیر و منابع Null با هم برابر می‌شوند. در گذشته این خاصیت دارای مجادله بود تا زمانی که علاوه بر چارچوب دات‌نت ۲، به هسته CLR نیز مجهز شد و همه تکنولوژی‌ها نظیر سی‌شارپ، ویژوال بیسیک، مایکروسافت اس‌کیوال سرور ۲۰۰۵ و مایکروسافت ویژوال استودیو ۲۰۰۵ را شامل شد.

 Coalesce Operator 
مقدار اولین عملوندی که null نباشد را برمی‌گرداند. (یا null، برای زمانی که تمام عملوندها null باشند)

object nullObj = null;
object obj = new Object();
return nullObj ?? obj;// returns obj

کاربرد اصلی این عملگر در قرار دادن یک مقدار nullable در یک مقدار non-nullable با استفاده از یک دستورالعمل ساده است.

int? i = null;
int j = i ?? 0; /* Unless i is null, initialize j to i. Else (if i is null), initialize j to 0. */

 ویژگی‌های جدید در سی‌شارپ ۳٫۰ 
این ورژن در تاریخ ۱۹ نوامبر سال ۲۰۰۷ به عنوان بخشی از چارچوب دات‌نت ۳٫۵ عرضه شد؛ که شامل ویژگی‌های جدید الهام شده از زبان‌های برنامه‌نویسی اصلی (Functional) مانند Haskell و ML، و الگوی LINQ برای CLR است. در حال حاضر توسط هیچ موسسه استانداردسازی تأیید نشده است.

 معرفی لینک 

لینک  یک زبان پرس و جوی قابل انعطاف و همه منظوره برای بسیاری از انواع منبع داده‌ها است (مثل انتخاب اشیاء شناور، سندهای XML، بانک‌های اطلاعاتی و…) که در ویژگی‌های سی‌شارپ ۳ جمع شده‌اند.
سینتکس زبان به زحمت از SQL گرفته شده است، برای مثال:

int[] array = { 1, 5, 2, 10, 7 };

// Select squares of all odd numbers in the array sorted in descending order
IEnumerable<int> query = from x in array
                         where x % 2 == 1
                         orderby x descending
                         select x * x;

 مقدار دهی به اشیاء 
Customer c = new Customer(); c.Name = "James";
عبارت بالا می‌تواند به صورت زیر نوشته شود:

Customer c = new Customer { Name="James" };

 مقدار دهی Collection 
MyList list = new MyList();
list.Add(1);
list.Add(2);

عبارت بالا می‌تواند به صورت زیر نوشته شود:

MyList list = new MyList { 1, 2 };

فرض کنید که اجزای MyList و System.Collections.IEnumerable دارای متد عمومی Add هستند.

 انواع داده‌ای بی‌نام 
var x = new { FirstName="James", LastName="Frank" };

سی‌شارپ ۲٫۰ توابع بی‌نام را معرفی کرد. سی‌شارپ ۳٫۰ هم انواع بی‌نام را معرفی می‌کند. با استفاده از این ویژگی برنامه نویسان قادر خواهند بود به صورت Inline انواع دلخواه خود را ایجاد کنند. به نمونه زیر توجه کنید:

static void Main(string[] args)
{
    var anonymousType = new { Name = string.Empty, Age = 0 };
}

کد ارائه شده، یک نوع بی‌نام را تعریف می‌کند که از طریق متغیر ضمنی محلی به نام anonymousType در اختیار قرار می‌گیرد.

چرا Anonymous types؟ انواع بی‌نام بهترین گزینه برای تولید Entity Typeها می‌باشند. همان‌طور که گفته شد Entity Typeها فقط حاوی داده‌ها هستند؛ بنابراین به بهترین نحو می‌توان داده‌های دریافت شده از کاربر را در انواع بی‌نام بسته‌بندی کرد.

 نتیجه نوع متغیر محلی 
var x = new Dictionary<string, List<float>>();

کد بالا با کد زیر قابل تعویض می‌باشد:

Dictionary<string, List<float>> x = new Dictionary<string, List<float>>();

این ویژگی تنها یک ntactic sugarراحت برای کوتاه‌تر بیان کردن متغیرهای محلی نمی‌باشد، بلکه برای تعریف متغیرهای بی‌نام لازم نیز است.

 عبارات لامبدا 
عبارات لامبدا یک راه کوتاه برای نوشتن مقادیر توابع بی‌نام کلاس اول را فراهم می‌کنند. دو مثال زیر را در نظر بگیرید:

listOfFoo.Where(delegate(Foo x) { return x.Size> 10; })

listOfFoo.Where(x => x.Size> 10);

در مثال‌های فوق، عبارات لامبدا صرفاً یک نوع سینتکس برای delegateهای بی‌نام با مقادیر دارای بازگشت هستند. هر چند با توجه به نوع متن استفاده می‌شوند، کامپایلر سی‌شارپ می‌تواند لامبداها را به ASTها نیز تبدیل کند تا بعداً در زمان اجرا نیز بتوانند پردازش شوند. در مثال فوق، اگر listOfFoo یک مجموعه ساده داخل حافظه نباشد، ولی یک پوشه در اطراف جدول بانک اطلاعاتی می‌باشد. این تکنیک می‌تواند برای بهینه کردن اجرا، برای ترجمه بدنه لامبدا به عبارت معادل آن در SQL استفاده شود. در هر یک از دو راه فوق، خود عبارت لامبدا دقیقاً شبیه کد به نظر می‌رسد، بنابراین روش استفاده در زمان اجرا، برای کاربر ناپیدا می‌باشد.

یکی از ویژگی‌هایی که سی‌شارپ ۲٫۰ ارائه کرد، توانایی تعریف توابع به صورت Inline بود که این ویژگی با عنوان توابع بی‌نام (anonymous methods) شناخته می‌شود. توابع بی‌نام در پاره‌ای مواقع بسیار مفیدند. اما نحو(syntax) به‌کارگیری آنها دشوار می‌باشد. عبارات لامبدا ویژگی توابع بی‌نام را دارند اما با نحو ساده‌تری در سی‌شارپ ۳٫۰ معرفی شده‌اند. به نمونه زیر توجه کنید:

static void Main(string[] args)
{
   (int x) => x + 1;// explicitly typed parameter
   (y, z) => y * z;// implicitly typed parameter
}

تعریف عبارات لامبدا از نحو (syntax) خاصی پیرو می‌کند. همان‌طور که در کد بالا مشاهده می‌کنید، پارامترهای تابع هم به صورت صریح و هم به صورت ضمنی قابل بیان اند. کلمه return به صورت ضمنی حذف شده است.
تابع معادل عبارت لامبدای اول به صورت زیر است:

int Fn(int x)
{
    return x+1;
}

لیست پارامترها و بدنه عبارت لامبدا توسط => از هم جدا می‌شوند. در صورتی که تعریف عبارت لامبدا بیشتر از یک خط کد باشد می‌توان بدنه آن را با استفاده از {} نشان داد.

static void Main(string[] args)
{
    (int x) => { x + 1; return x * x; };
}

 خواص خودکار 
کامپایلر به‌طور خودکار یک متغیر نمونه خصوصی و قرار دهنده و قرار گیرنده مناسب تولید می‌کند، مانند:

 public string Name { get; private set; }

 توابع بسط داده شده 
توابع بسط داده شده حالتی از سینتکس Suger هستند که امکان اضافه کردن متد جدید به کلاس موجود را بیرون از حوزه تعریف آن فراهم می‌کنند. در این مثال، تابع بسط داده شده یک تابع ایستا است که قابل فراخوانی توسط تابع مشابه می‌باشد. گیرنده فراخوانی مقید به اولین پارامتر تابع تحت عنوان this می‌باشد:

public static class StringExtensions
{
    public static string Left(this string s, int n)
    {
        return s.Substring(0, n);
    }
}

string s = "foo";
s.Left(3);// same as StringExtensions.Left(s, 3);

زبان سی‌شارپ کلمه کلیدی sealed را برای این منظور ارائه کرد که امکان ارث بری از یک کلاس را صلب کند؛ یعنی با اضافه شدن این کلمه کلیدی به ابتدای تعریف کلاس، امکان ارث بری از آن غیرممکن می‌شود. سی‌شارپ ۳٫۰ ویژگی جدیدی را در اختیار برنامه نویسان قرار می‌دهد به این صورت که می‌توان هر نوع کلاسی حتی کلاس‌های مهر شده با Sealed را با استفاده از Extension methodsبسط داد.

 توابع جزئی 
توابع جزئی به تولیدکننده‌های کد اجازه تولید اعلان توابع به صورت نقاط گسترش یافته‌ای که تنها شامل کدهای اصلی هستند را می‌دهد، در صورتی که یک نفر آن را در قسمتی از کلاسی دیگر اجرا کند.

 متغیرهای ضمنی محلی 
سی‌شارپ ۳٫۰ کلمه کلیدی جدید var را معرفی می‌کند که به کمک آن برنامه نویسان قادر خواهند بود متغیرهای محلی خود را بدون ذکر صریح نوع آن‌ها، تعریف کنند.

namespace CS3_Test
{
    class Program
    {
        static void Main(string[] args)
        {
            var string_value = "Hello C# 3.0";
            var int_value = 3;
        }
    }
 }

یکی از ویژگی‌های اصلی زبان سی‌شارپ،Strong Type بودن آن است. Strong Type بودن زبان به این معناست که با اعلان یک متغیر، نوع آن صریحاً باید توسط برنامه‌نویس مشخص شود. آیا اضافه شدن این ویژگی جدید، منافاتی با Strong Type بودن این زبان دارد؟ در پاسخ باید گفت که تعریف متغیرهای محلی به صورت ضمنی با استفاده از کلمه کلیدی var هیچ گونه منافاتی با Strong Type بودن سی‌شارپ ندارد. چون برنامه‌نویس می‌بایست نوع متغیر را به هنگام اعلان آن صریحاً مشخص کند. نوع متغیر پس از اولین اعلان تا اتمام حوزه تعریف آن تغییر نخواهد کرد و هر گونه تلاش برای تغییر نوع با خطا مواجه خواهد شد؛ بنابراین دو اعلان زیر نامعبر هستند:

namespace CS3_Test
{
    class Program
    {
        static void Main(string[] args)
        {
            var string_value;// Error: Implicitly typed locals must be inintialized
            var int_value = null; /* Error: Cannot assign '<null>' to an implicitly typed local */
        }
    }
}

استفاده از var تنها در تعریف متغیرهای محلی امکانپذیر است. در اعلان متغیرها به صورت سراسری، پارامترهای توابع و مقادیر بازگشتی نمی‌توان از var استفاده کرد. چرا var؟ این ویژگی آزادی عملی بیشتری برای کار با متغیرهای محلی در اختیار برنامه‌نویس قرار می‌دهد. سناریویی را در نظر بگیرید که یک تابع تحت شرایطی، مقادیر از انواع مختلف را برگرداند. در این صورت بدون درگیر شدن با casting و تبدیل نوع می‌توان با تعریف متغیر ضمنی محلی هر نوعی را که تابع برمی‌گرداند، در اختیار داشت.

 سازنده‌های پیشرفته 
ماهیت تمامی برنامه‌های امروزی به گونه‌ای‌ست که با حجم عظیمی از داده‌ها سرو کار دارند. برای مدیریت داده‌ها، نیاز به کلاس‌هایی‌ست که در مهندسی نرم‌افزار آنها را Entity Types می‌نامیم. این کلاس‌ها به عنوان بسته‌هایی از داده‌ها محسوب می‌شوند. معضل فعلی موجود در رابطه با Entity Typeها تعدد سازنده‌های آن‌ها می‌باشد و ممکن است شما نیز با این مشکل برخورد کرده باشید. به این صورت که در سناریوهای مختلف، برنامه‌نویسان مجبور هستند سازنده یک کلاس را به چند شکل سربارگذاری کنند. سی‌شارپ ۳٫۰ راه چاره‌ای فوق‌العاده برای این مشکل ارائه می‌دهد. Object initializer حالت پیشرفته‌ای از سازنده می‌باشد.

class Person
{
    private string firstname;

    public string FirstName
    {
        get { return firstname; }
        set { firstname = value; }
    }

    private string lastname;

    public string LastName
    {
        get { return lastname; }
        set { lastname = value; }
    }

    private int age;

    public int Age
    {
        get { return age; }
        set { age = value; }
    }
}

این کلاس شامل سه متغیر بوده و برای هر متغیر خاصیتی تعریف شده است. اینک این سوالات مطرح می‌شوند: سازنده این کلاس را به چند شکل باید سربارگذاری کرد؟ سازنده‌ای که هر سه متغیر را مقداردهی کند؟ شاید در مواردی هر سه متغیر در دست نباشد در این صورت چه سازنده‌ای باید فراخوانی شود؟ سی‌شارپ ۳٫۰ راه حل زیر را ارائه می‌دهد. فرض کنید بخوانیم نمونه‌ای از کلاس Person را ایجاد کنیم.
همان‌طور که مشاهده می‌کنید، در سی‌شارپ ۳٫۰ به هنگام نمونه سازی، این امکان در اختیار برنامه‌نویس قرار می‌گیرد که هر یک از خصیصه‌های موجود در کلاس را به دلخواه و بنا به نیاز مقدار دهی کند به صورت زیر:

Person person = new Person
(    Age = 21,
    FirstName = "James",
    LastName = "Frank");

 عبارات جستجو (Query Expression) 
تیم طراح سی‌شارپ ویژگی فوق‌العاده‌ای را به آن اضافه کرد که برنامه نویسان را قادر می‌سازد نحو (Syntax) زبان‌های پرس و جو مانند اس‌کیوال و اکس‌کوئری را با استفاده از این زبان پیاده‌سازی کنند. این ویژگی با نام اختصاری LINQ شناخته می‌شود و دارای انواع زیر است:
 LINQ-to-Objects - talks to in-memory objects
 LINQ-to-SQL - talks to SQL Server databases
 LINQ-to-XML - talks to hierarchical data represented in XML
 LINQ-to-DataSets - talks to DataSet objects and underlying DataTables with their relationships
 LINQ-to-Entities - talks to "entities", part of ADO.NET ۳٫۰

نمونه‌ای از کاربرد LINQ به صورت زیر است:

static void Main(string[] args)
{
    var int_array = new int[] { 1, 2, 7, 9, 12 };

    var selective_array = from c in int_array where c> 5 select c;

    foreach (var selected in selective_array)
    {
        Console.WriteLine(selected);
    }
}

توضیح: در مثال بالا ابتدا یک آرایهٔ int با مقداردهی اولیه تعریف شده است. سپس با استفاده از دستورها) LINQ که جز کلمات کلیدی سی‌شارپ محسوب می‌شوند)، آرایه‌ای با اعضای بزرگتر از ۵ انتخاب و در متغیر ضمنی محلی selective_array ذخیره می‌شود. در نهایت اعضای selective_array به صورت ۷ و ۹ و ۱۲ خواهد بود. در توضیح این ویژگی جدید به همین یک مثال بسنده می‌کنیم چون بیان تمامی جنبه‌های LINQ خود نیازمند نگارش مقاله‌ای مفصل می‌باشد.

 آرایه‌های نوع ضمنی 
آرایه‌ها را نیز می‌توان با استفاده از کلمه کلیدی var تعریف کرد.

static void Main(string[] args)
{
    var a = new[] { 1, 10, 100, 1000 };// int[]
    var b = new[] { 1, "one", 2 };// Error
}

 پیش پردازنده 
ویژگی «دستورها پیش پردازنده» سی‌شارپ (اگرچه آنها به واقع یک پیش پردازنده نیستند) مبنی بر دستورها پیش پردازنده C است که به برنامه‌نویس اجازه تعریف سمبلهایی را می‌دهند. برخی از این دستورها عبارتند از: #if، #region، #define. راهنماهایی نظیر #region تذکراتی به ویرایش‌گرها برای code folding می‌دهند.

 توضیحات کد 
توضیحات تک خط با استفاده از دو اسلش تعریف می‌شوند(//) و توضیحات چند خطی با /* شروع و به */ ختم می‌شوند.

public class Foo
{
// a comment
    public static void Bar(int firstParam) {}//Also a comment
}

public class FooBar
{
    /* a comment */
    public static void BarFoo(int firstParam) {}  /* Also a comment */

توضیحات چند خطی هم چنین می‌توانند با /* شروع و با */ تمام شوند.

public class Foo
{
    /* A Multi-Line
       comment  */
    public static void Bar(int firstParam) {}
}

 سامانه مستندسازی XML 
سامانه مستندسازی سی‌شارپ بسیار شبیه به جاوا است، اما مبنی بر XML. دو شیوه مستندسازی در حال حاضر به وسیله کامپایلر سی‌شارپ پشتیبانی می‌شود.

توضیحات تک خطی، که معمولاً در تولیدکننده کد مایکروسافت ویژوال استودیو پیدا می‌شوند، با استفاده از/// شروع می‌شوند.

public class Foo
{
/// <summary>A summary of the method.</summary>
/// <param name="firstParam">A description of the parameter.</param>
/// <remarks>Remarks about the method.</remarks>
    public static void Bar(int firstParam) {}
}

توضیحات چند خطی، که در نسخه ۱٫۰ تعریف شدند، اما در نسخه ۱٫۱ پشتیبانی از آنها وجود نداشت با /* شروع و به */ ختم می‌شوند:

public class Foo
{
    /** <summary>A summary of the method.</summary>
     *  <param name="firstParam">A description of the parameter.</param>
     *  <remarks>Remarks about the method.</remarks> */
    public static void Bar(int firstParam) {}
}

نکته:در اینجا یک ملاک سخت در مورد استفاده از فضاهای خالی در سندهای XML هنگام استفاده از /**وجود دارد:

/**
 * <summary>
 * A summary of the method.</summary>*/

نوع دیگری از کد بالا ارائه خواهد شد:

/**
 * <summary>
   A summary of the method.</summary>*/

سینتکس سندسازی توضیحات XML در یک ضمیمه بی‌قاعده از استاندارد ECMA از سی‌شارپ وجود دارد. یک استاندارد مشابه قوانینی برای پردازش توضیحات و تبدیل آنها به متون Plain در XML را با کمک قوانین CLI فراهم می‌کند. این به هر IDE در سی‌شارپ و دیگر ابزار گسترش دهنده امکان پیدا کردن هر نمادی را در کدها می‌دهد.

 (CLR(Common Language Runtime 
بخش مرکزی چارچوب دات‌نت، محیط اجرایی Runtime می‌باشد که اصطلاحاً به آن CLR یا .NET Runtime می‌گویند. کدهایی که تحت کنترل CLR اجرا می‌شوند اغلب به عنوان کدهای مدیریت شده نامیده می‌شوند.

اگر چه، پیش از این که کدها (همه زبان‌های چارچوب دات‌نت) به وسیله CLR اجرا شوند، بایستی مورد کامپایل قرار گیرند. در چارچوب دات‌نت عمل کامپایل در دو مرحله صورت می‌گیرد:
 کامپایل سورس کد به MSIL.
 کامپایل MSIL به کد مختص پلتفرم به وسیله CLR

یک نکته قابل توجه، اشتراک زبان میانی مایکروسافت با کد بایت جاوا(Bytecode)است. ایده این اشتراک از آنجا سرچشمه گرفت که چون Bytecode یک زیان سطح پایین با یک دستور زبان ساده می‌باشد (که به جای متن مبتنی بر کدهای عددی است)، می‌تواند به سرعت به کدهای بومی(Native) ترجمه شود.

 برخی ویژگی‌های MSIL 
 شیءگرایی و به‌کارگیری واسط‌ها
 تمایز فراوان بین انواع مقداری و ارجاعی
 تعیین Strong Type (این نوع داده دیگر معتبر نیست)
 مدیریت خطا از طریق به‌کارگیری Exception
 به‌کارگیری صفات

 اشکالات 
 پلتفرم 
منبع چارچوب دات‌نت مایکروسافت برای اجرا فقط ویندوز است. پیاده‌سازی‌های دیگری برای اجرای برنامه‌های سی‌شارپ در ویندوز، لینوکس،BSD یا Mac OS X وجود دارند اما هنوز کامل نیستند: Mono و DotGNU در نوامبر سال ۲۰۰۲ توسط مایکروسافت (نسخه ۱٫۰) برای پیاده‌سازی CLI برای کار در Free BSD و Mac OS X ۱۰٫۲ ارائه شد، اما نسخه‌های بعدی آنها فقط قابل اجرا بر روی ویندوز بود.

 پیشرفت در آینده 
نسخه بعدی این زبان، سی‌شارپ ۴ است که از اکتبر سال ۲۰۰۸ در حال ساخته شدن است. مایکروسافت لیستی از ویژگی‌های جدید سی‌شارپ ۴ را در کنفرانس توسعه دهندگان حرفه‌ای اعلام کرده است. تمرکز اصلی در ورژن بعدی روی قابلیت هماهنگی فریم ورک‌ها و نوع زبان‌هایی است که کامال پویا یا قیمتی پویا هستند، مانند dynamic language runtime و COM. ویژگی‌های زیر تا کنون اعلام شده‌اند:

 پارامترهای نوع generic از نوع Covariant و contravariant 
پارامترهای واسط‌های generic و deletageها می‌توانند با استفاده از کلمات out و in از دو نوع Covariant و contravariant باشند. این تعیین نوع‌ها بعداً برای تبدیل انواع به یکدیگر، چه از نوع صریح یا مجازی و چه از نوع compile-time یا run-time به کار می‌رود. به عنوان مثال، واسط IEnumerable<T> در زیر دوباره تعریف شده است:

interface IEnumerable<out T>
{
  IEnumerator<T> GetEnumerator();
}

بنابراین، هر کلاس مشتق شده‌ای که از IEnumerable<Derived> استفاده کرده باشد، با تمام کلاس‌های پایه که IEnumerable<Base> را دارند سازگار است. به عنوان تمرین، کد زیر نوشته شده است:

void PrintAll(IEnumerable<object> objects)
{
  foreach (object o in objects)
  {
    Console.WriteLine(o);
  }
}

IEnumerable<string> strings = new List<string>();
PrintAll(strings);// IEnumerable<string> is implicitly converted to IEnumerable<object>

برای contravariance، رابط IComparer<T> به صورت زیر دوباره تعریف شده است:

public interface IComparer<in T>
{
    int Compare(T x, T y);
}

بنابراین، هر کلاسی که IComparer<Base> را برای یک کلاس پایه بیان می‌کند، با IComparer<Derived> در تمام واسط‌ها و کلاس‌هایی که از آن کلاس پایه مشتق شده‌اند، سازگار است. این امر نوشتن کد زیر را میسر می‌سازد:

IComparer<object> objectComparer = GetComparer();
IComparer<string> stringComparer = objectComparer;

 جستجوی عضو پویا 
در سامانه انواع داده‌های سی‌شارپ یک نوع جدید با نام شبه-نوع معرفی شده است که مانند System.Object رفتار می‌کند، ولی در ادامه، هر دسترسی به اعضا یا برنامه‌هایی که از این نوع استفاده می‌کنند، بدون چک شدن نوع داده‌هایشان اجازه کار دارند و تجزیه آنها تا زمان اجرا به تعویق می‌افتد. به عنوان مثال:

// Returns the value of Length property or field of any object
  int GetLength(dynamic obj)
  {
    return obj.Length;
  }

  GetLength("Hello, world");// a string has a Length property,
  GetLength(new int[] { 1, 2, 3 });// and so does an array,
  GetLength(42);// but not an integer - an exception will be thrown here at run-time

صدا زده شدن‌های متد پویا، مانند پارامترهای صریح یا مجازی با مقدار نوع dynamic راه‌اندازی می‌شوند. به عنوان مثال:

 void Print(dynamic obj)
  {
     Console.WriteLine(obj);// which overload of WriteLine() to call is decided at run-time
  }

  Print(123);// ends up calling WriteLine(int)
  Print("abc");// ends up calling WriteLine(string)

جستجوی پویا تحت سه مکانیزم مشخص اجرا می‌شود: COM IDispatch برای اشیاء COM، رابط IDynamicObject DLR برای اشیاء دارای این واسط و Reflection برای بقیه اشیا؛ بنابراین هر کلاس سی‌شارپ می‌تواند صدا زده شدن‌های پویای خود را با اجرای IDynamicObject در نمونه‌های خود جدا کند.
در مورد متدهای پویا و مشخص کننده صدا زدن‌ها، تجزیه و تحلیل اضافه بار مطابق انواع اصلی که به عنوان آرگومان‌ها هستند، در زمان اجرا اتفاق می‌افتد، در غیر این صورت بر اساس قوانین تجزیه و تحلیل اضافه بار سی‌شارپ عمل خواهد شد. به علاوه، در مواردی که در صدا زدن پویا، گیرنده خودش پویا نیست، تجزیه و اضافه بار زمان اجرا تنها به متدهایی که در زمان کامپایل به صورت گیرنده ظاهر شده‌اند، رسیدگی می‌کند. به عنوان مثال:

class Base
{
  void Foo(double x);
}

class Derived: Base
{
  void Foo(int x);
}

dynamic x = 123;
Base b = new Derived();
b.Foo(x);// picks Base.Foo(double) because b is of type Base, and Derived.Foo(int) is not exposed
dynamic b1 = b;
b1.Foo(x);// picks Derived.Foo(int)

هر مقداری که توسط دستیابی به عضو پویا برگردانده شده باشد، خودش از نوع پویا است. مقادیر نوع پویا به سایر نوع‌ها و از سایر نوع عا قابل تبدیل هستند. در نمونه کد بالا، این امر به تابع GetLength اجازه با مقدار بازگردانده شده از Length بدون هیچ صریحی به عنوان integer استفاده کند. در زمان اجرا، مقدار واقعی به نوع خواسته شده تبدیل می‌شود.

 کلمه کلیدی اختیاری ref 
در حال حاضر کلمه کلیدی ref برای متدهای صدا زننده اختیاری است. کد زیر را در نظر بگیرید:

void Increment(ref int x)
{
  ++x;
}

int x = 0;
Increment(ref x);

به صورت زیر هم می‌تواند نوشته شود:

void Increment(ref int x)
{
  ++x;
}

int x = 0;
Increment(x);

 آرگومان‌های نام گذاری شده و پارامترهای اختیاری 
در سی‌شارپ ۴ پارامترهای اختیاری ای با مقادیر پیش فرض موجود در ++C معرفی می‌شوند. به عنوان مثال:

void Increment(ref int x, int dx = 1)
{
  x += dx;
}

int x = 0;
Increment(ref x);// dx takes the default value of 1
Increment(x, 2);// dx takes the value 2

به علاوه، برای کامل کردن پارامترهای اختیاری، می‌توانید صریحاً نام پارامترها را در صدازدن‌های متدها تعیین کنید. این کار به شما اجازه تصویب کردن انتخابی برای هر زیر مجموعه اختیاری از پارامترهای متد را می‌دهد. تنها محدودیت موجود این است که پارامترهای نام دار باید بعد از پارامترهای بدون نام بیایند. نام پارامترها می‌توانند برای هر دو نوع پارامترهای اختیاری و ضروری تعیین شوند و می‌توانند برای بهبود خوانایی و فراخوانی دوباره آرگومان‌ها مفید باشند. به عنوان مثال:

Stream OpenFile(string name, FileMode mode = FileMode.Open, FileAccess access = FileAccess.Read) { ... }

OpenFile("file.txt");// use default values for both "mode" and "access"
OpenFile("file.txt", mode: FileMode.Create);// use default value for "access"
OpenFile("file.txt", access: FileAccess.Read);// use default value for "mode"
OpenFile(name: "file.txt", access: FileAccess.Read, mode: FileMode.Create);// name all parameters for extra readability, and use order different from method declaration

پارامترهای اختیاری inter-operating را با COMراحت تر می‌کنند. در گذشته، سی‌شارپ مجبور بود تمام پارامترهای متد سازنده COM را پشت سر بگذارد، حتی آنهایی را که اختیاری بودند؛ به عنوان مثال:

object fileName = "Test.docx";
object missing = System.Reflection.Missing.Value;

doc.SaveAs(ref fileName,
    ref missing, ref missing, ref missing,
    ref missing, ref missing, ref missing,
    ref missing, ref missing, ref missing,
    ref missing, ref missing, ref missing,
    ref missing, ref missing, ref missing);

با پشتیبانی از پارامترهای اختیاری، کد بالا می‌تواند به صورت زیر خلاصه شود:

doc.SaveAs("Test.docx");

 کتابخانه‌ها 
جزئیات مشخصات سی‌شارپ، حداقل تعداد نوع‌ها و کتابخانه‌های کلاس است که کامپایلر نیاز به وجود آن‌ها دارد. عملاً، اغلب سی‌شارپ توسط بیشترین استفاده از CLI را می‌کند، که استاندارد شده ECMA-۳۳۵ است.

 مثال Hello world 
در زیر یک مثال ساده از برنامه سی‌شارپ آمده است، نسخه‌ای از مثال کلاسیک Hello World:

class ExampleClass
{
    static void Main()
    {
        System.Console.WriteLine("Hello, world!");
    }
}
 نتیجه، چاپ شدن متن زیر در خروجی است:

Hello, world!

هر خط هدفی دارد:

class ExampleClass

در بالا، تعریف کلاس آمده است. هر چیزی که در بین در علامت پرانتز باشد،ExampleClass را توصیف می‌کند:

static void Main()

این یک تابع عضو کلاس را در زمان شروع اجرای برنامه اعلان می‌کند. دات نت در زمان اجرا، تابع Main را صدا می‌زند (نکته: Main ممکن است از هر جای دیگری نیز صدا زده شود، مثلاً توسط تابع ExampleClass و با کد ()Main). کلمه کلیدی static تابع را بدون داشتن نمونه‌ای از ExampleClass قابل دسترس می‌کند. هر تابع Main در هر کنسولی باید به صورت static تعریف شود. در غیر این صورت برنامه به یک نمونه نیاز خواهد داشت و هر نمونه به یک برنامه نیاز دارد. برای اجتناب از این وابستگی دایره‌ای تجزیه ناپذیر، کامپایلرهای سی‌شارپ در صورت Static نبودن تابع Main، یک خطا اعلام می‌کنند. کلمه کلیدی void نشان دهنده این است که تابع Main هیچ مقداری را برنمی‌گرداند.

Console.WriteLine("Hello, world!");

خط بالا، خروجی را می‌نویسد. در فضای اسم System, Console یک کلاس استاتیک است که یک میانجی بین ورودی، خروجی و خطای کنسول می‌باشد. برنامه‌ای که متد WriteLine را از کنسول صدا می‌زند، خروجی رشته «Hello, world!» را در خروجی نمایش می‌دهد.

راه دیگر این کار استفاده از فضای نام استاتیک است به این صورت است:

using static System.Console;
class ExampleClass
{
    static void Main()
    {
       WriteLine("Hello, world!");
    }
}

 استانداردسازی 
در اوت سال ۲۰۰۰، شرکت مایکروسافت، و هیولت پاکارد و شرکت اینتل به عنوان پشتیبان مشخصات سی‌شارپ را مانند CLI به سازمان استانداردسازی اکما اینترنشنال ارائه کردند. در دسامبر سال ۲۰۰۱، این سازمان، ECMA-۳۳۴ را با عنوان مشخصات زبان سی‌شارپ منتشر کرد. سی‌شارپ در سال ۲۰۰۳ به عنوان یک استاندارد ISO به ثبت رسید(ISO/IEC ۲۳۲۷۰). در سال ۲۰۰۲، ECMA دومین ویرایش از خصوصیات زبان سی‌شارپ را پذیرفت.

در ژوئن سال ۲۰۰۵، ECMA سومین ویرایش را با اضافه کردن مواردی همچون کلاس‌های partial، متدهای ناشناس، انواع nullable و Genericها منتشر کرد.
در ژوئیه ۲۰۰۵، ECMA استانداردها و TRها را همراه با پردازش Fast-Track اخیر به ISO/IEC JTC پیشنهاد کرد. این روند معمولاً ۶ تا ۹ ماه زمان می‌برد.
آخرین ویرایش این زبان در ۱۵ اوت سال ۲۰۱۲ در قالب Framework ۴٫۵ ارائه گردید

 کارایی 
با توجه به توابع موجود در چارچوب دات‌نت امکان استفاده از این توابع وجود دارد که می‌توان گفت برای هر کاری شرکت مایکروسافت تابعی پیش‌بینی کرده؛ که این امکان را ایجاد می‌کند که به فایل اصلی پروژه هیچ فایل کتابخانه‌ای را اضافه نکنید (هم به صورت دستی یا خود کامپایلر).
این موضوع خود باعث ایجاد فایل‌های خروجی با حجم بسیار کم می‌شود. این موضوع در بسیاری از موارد بسیار اهمیت دارد.
برنامه‌های سی‌شارپ، همچون تمام برنامه‌های نوشته شده در چارچوب دات‌نت و سایر محیط‌های ماشینی مجازی مانند جاوا، نیازمند منابع سامانه و حافظه بیشتری نسبت به برنامه‌های نوشته شده با سایر زبان‌ها مانند سی پلاس پلاس است و هم چنین سرعت کمتری نیز دارد.
هر چند تعریف زبان سی‌شارپ و CLI تحت استانداردهای ISO و ECMA استاندارد شده‌اند،CLI تنها قسمتی از Base Class Library (BCL) مایکروسافت می‌باشد که شامل کلاس‌های غیر استاندارد استفاده شده در برنامه‌های سی‌شارپ نیز می‌شود. از این گذشته، بعضی از قسمت‌های BCL تحت حق امتیاز مایکروسافت هستند که ممکن است پیاده‌سازی کامل framework را مختل کند، زیرا تنها بخش‌های استاندارد دارای حق محافظت RAND در برابر مدعیان را دارند. همچنین در ساخت انواع برنامه‌های کاربردی از قبیل CRMها نیز قابل استفاده می‌باشد.

 بازی حدس عدد به زبان C# 
بازی حدس عدد یک مسئله‌ی کلاسیک مقدماتی در برنامه‌نویسی است که ما در اینجا قصد داریم آن را با استفاده از زبان برنامه‌نویسی C# پیاده‌سازی کنیم. کارکرد این بازی به این صورت است که ابتدا برنامه یک عدد صحیح تصادفی بین 1 تا 100 تولید می‌کند و سپس از بازیکن خواسته می‌شود که این عدد را حدس بزند. اگر حدس او صحیح باشد، یک پیغام تبریک برای وی نمایش داده خواهد شد و در غیر این صورت، پیغامی نمایش داده خواهد شد که مشخص می‌کند عددی که حدس زده از عدد مورد نظر کوچکتر است یا بزرگتر تا بازیکن حدس بعدی را بر اساس آن تعیین کند.

 ایجاد و تنظیم یک پروژه جدید 
C# زبانی است که در سال ۲۰۰۲ به همراه فریمورک .NET توسط مایکروسافت معرفی شد. از ان زمان تا امروز، تغییرات زیادی در معماری فریمورک .NET که حالا دیگر به معنای واقعی کلمه Cross-platform یا مستقل از پلتفرم است و زبان برنامه نویسی C# به وجود امده است.

C# یک زبان استاتیک و کامپایلری است که مثل جاوا کامپایل برنامه را در دو مرحله انجام می‌دهد. در مرحله‌ی اول، کدها نه به زبان ماشین بلکه به یک زبان میانی و شبه‌اسمبلی به نام CIL کامپایل می‌شود و در مرحله‌ی دوم، هنگام اجرا این کدهای CIL به کد ماشین تبدیل می‌شوند.

C# یک زبان برنامه‌نویسی قدرتمند و چند منظوره است که از حمایت مایکروسافت برخوردار است. برای تسلط به این زبان و رسیدن به توانایی خلق انواع اپلیکیشن‌ها با استفاده از آن، دوره جامع آموزش برنامه‌نویسی با C# را به شما پیشنهاد می‌دهیم.

قبل از اینکه شروع به نوشتن بازی حدس عدد کنیم، ابتدا مطمئن شوید که .NET SDK روی سیستم شما نصب باشد. برای این کار، کامند زیر را تست کنید:> dotnet --list-sdks
8.0.204 [C:\Program Files\dotnet\sdk]خروجی کامند باید چیزی شبیه بالا باشد که حاکی از نصب نسخه‌ی 8 از .NET SDK است. البته روی سیستم شما ممکن است نسخه‌ی متفاوتی نصب باشد.

در ضمن، ما در اینجا از Visual Studio Code برای ساخت برنامه استفاده می‌کنیم اما شما می‌توانید از Visual Studio یا هر IDE دیگری که مایلید، استفاده کنید.

برای ایجاد پروژه، ابتدا یک دایرکتوری به نام GuessTheNumber ایجاد کنید و آن را در vscode باز کنید. سپس، کامند زیر را در ترمینال vscode اجرا کنید:> dotnet new console --framework net8.0 --use-program-mainدر نسخه‌های قدیمی‌تر .NET یک یا چند عبارت using نیز در بالای فایل Program.cs دیده می‌شد که باعث اضافه‌شدن چند فضای نام پرکاربرد به پروژه می‌شد. اما در نسخه‌های اخیر، این فضاهای نام و از جمله فضای نام System به طور ضمنی به پروژه اضافه می‌شوند و اعضای آنها در دسترس برنامه قرار دارند.

در اولین خط این فایل، عبارت namespace GuessTheNumber; دیده می‌شود که به این معناست که یک فضای نام هم‌نام با پروژه به برنامه اختصاص داده شده است. سپس، کلاس Program را می‌بینیم که در صورت تمایل، می‌توانیم هر نام دیگری را به آن اختصاص دهیم و درون این کلاس متد main دیده می‌شود که نقطه‌ی ورود یا Entry point برنامه‌های اجرایی C# محسوب می‌شود. یعنی با اجرای برنامه، کدهای این فایل اجرا می شوند.

در ادامه، با ویرایش این فایل و نوشتن کدهای مورد نظرمان، بازی حدس عدد را پیاده‌سازی می‌کنیم.

برای دیدن تمامی مراحل نوشتن این بازی به منبع این مبحث مراجعه کرده و مراحل صفر تا صد پیاده سازی را ببینید.

 پیاده‌سازی‌ها 
متداول‌ترین کامپایلر سی‌شارپ، Microsoft Visual C# می‌باشد.
کامپایلرهای سی‌شارپ
 پروژه Microsoft Rotor (در حال حاضر به عنوان Shared Source Common Language Infrastructure شناخته می‌شود) (ثبت شده فقط برای استفاده آموزشی و تحقیقی) یک پیاده‌سازی منبع اشتراکی از CLR Runtime را فراهم می‌آورد و یک کامپایلر سی‌شارپ، و یک زیرمجموعه از کتابخانه]] CLI Framework مورد نیاز.
 پروژه Mono یک اوپن سورس از کامپایلر سی‌شارپ است، یک پیاده‌سازی اوپن سورس کامل از CLI شامل کتابخانه‌های Framework مورد نیاز که در ECMA ظاهر شده‌اند، و یک پیاده‌سازی کامل نزدیک به بقیه کتابخانه‌های اختصاصی کلاس چارچوب دات‌نت مایکروسافت.
 پروژه DotGNU نیز یک اوپن سورس از کامپایلر سی‌شارپ است، که پیاده‌سازی آن بسیار نزدیک به Common Language Infrastructure می‌باشد و کتابخانه‌های framework مورد نیاز موجود در ECMA و زیر مجموعه‌ای از کلاس‌های کتابخانه‌ای شخصی مایکروسافت در دات نت و دات نت ۲ را دربردارد.
کاملاً شبیه به پروژه Mono.

 نام زبان 
اسم سی‌شارپ از علامت موسیقی شارپ گرفته شده است که در موسیقی بیانگر این است که متن نوشته شده باید نیم قدم از خط بالاتر باشد. مطابق با ECMA-۳۳۴، بخش ۶، مخفف‌ها و اختصارها، نام زبان به صورت «#C» نوشته می‌شود(«کلمه لاتین C (U+۰۰۴۳) به همراه علامت عددی #(U+۰۰۲۳)») که به صورت «سی‌شارپ» تلفظ می‌شود. علامت «#» نباید با علامت شارپ در موسیقی(♯، U+266F) که در یک صفحه کلید استاندارد وجود ندارد اشتباه گرفته شود. پسوند شارپ، توسط بسیاری دیگر از زبان‌های دات نت مانند #J، #A و #F نیز به کار رفته است. پیاده‌سازی اولیه از زبان ایفل تحت دات نت نیز #Eiffel نام داشت که الان زبان ایفل را به‌طور کامل پشتیبانی می‌کند. هم چنین این پسوند بعضی وقت‌ها در کتابخانه‌ها نیز به کار می‌رود، مانند #Gtk، #Cocoa و #Qt.

 کلمات اختصاری به کار رفته در این متن 

 PDC: Professional Developers Conference
 IL (MSIL): Microsoft Intermediate Language
 ECMA: European Computer Manufacturers Association
 BCL: Base Class Library
 CLI: Common Language Infrastructure
 CLS: Common Language Specification
 IEC: International Electrotechnical Commission
 ISO: International Organization for Standardization
 SDK: Software Development Kit
 LINQ: Language Integrated Query

 جستارهای وابسته 
 اکس‌ام‌ال
 خدمات وب

 منابع 

 پیوند به بیرون 

 .NET Framework and .NET SDK Downloads

رده:اختراع‌های آمریکایی
رده:استانداردهای آی‌ئی‌سی
رده:استانداردهای ئی‌سی‌ام‌ای
رده:استانداردهای ایزو
رده:خانواده زبان‌های برنامه‌نویسی سی شارپ
رده:زبان‌های برنامه‌نویسی ایستا
رده:زبان‌های برنامه‌نویسی خانواده سی
رده:زبان‌های برنامه‌نویسی دات‌نت
رده:زبان‌های برنامه‌نویسی دارای استاندارد ایزو
رده:زبان‌های برنامه‌نویسی ساخته‌شده در ۲۰۰۰ (میلادی)
رده:زبان‌های برنامه‌نویسی ساخته‌شده در ۲۰۰۱ (میلادی)
رده:زبان‌های برنامه‌نویسی شیءگرا
رده:زبان‌های برنامه‌نویسی کلاس محور
رده:زبان‌های تابعی
رده:مونو
رده:نرم‌افزارهای ۲۰۰۰ (میلادی)
رده:ویژوال استودیو