ویژگیهای در سی شارپ
ویژگیهای جدید در سی شارپ چارچوب داتنت 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، پاسکال و...)
یک شکل جدید از تکرار کننده با استفاده از سازنده توابع
یک شکل جدید از iterator(تکرار کننده)، با استفاده از ساختار yield return بسیار شبیه به yield زبان Python.
// 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 است. در حال حاضر توسط هیچ موسسه استانداردسازی تائید نشدهاست.
معرفی لینک
لینک (به انگلیسی: Language Integrated Query)(مخفف انگلیسی: LINQ) یک زبان پرس و جوی قابل انعطاف و همه منظوره برای بسیاری از انواع منبع دادهها است (مثل انتخاب اشیا شناور، سندهای 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بسط داد.
توابع جزئی
توابع جزئی به تولید کنندههای کد اجازه تولید اعلان توابع به صورت نقاط گسترش یافتهای که تنها شامل کدهای اصلی هستند را میدهد، در صورتی که یک نفر آن را در قسمتی از کلاسی دیگر اجرا کند.