04-26-2011، 07:26 PM
ویژگیهای جدید در C# ۳.۰
این ورژن در تاریخ ۱۹ نوامبر سال ۲۰۰۷ به عنوان بخشی از .NET Framework ۳.۵ عرضه شد.که شامل ویژگیهای جدید الهام شده از زبانهای برنامه نویسی اصلی(Functional) مانند Haskell و ML، و الگوی LINQ برای CLR است.در حال حاظر توسط هیچ موسسه استاندارد سازی ای تائید نشدهاست.
معرفی (Language-Integrated Query(LINQ
LINQ، یک زبان پرس و جوی قابل انعطاف و همه منظوره برای بسیاری از انواع منبع داده هااست( مثل انتخاب اشیا شناور، سندهای XML، بانکهای اطلاعاتی و . . .) که در ویژگیهای ۳#C جمع شدهاند. سینتکس زبان به زحمت از SQL گرفته شدهاست، برای مثال:
[/quote]
مقدار دهی به اشیا
Customer c = new Customer(); c.Name = "James";
عبارت بالا میتواند به صورت زیر نوشته شود:
Customer c = new Customer { Name="James" };
مقدار دهی Collection
عبارت بالا میتواند به صورت زیر نوشته شود:
MyList list = new MyList { 1, 2 };
فرض کنید که اجزای MyList و System.Collections.IEnumerable دارای متد عمومی Add هستند.
انواع دادهای بی نام
var x = new { FirstName="James", LastName="Frank" };
C# ۲.۰توابع بی نام را معرفی کرد. C# ۳.۰هم انواع بی نام را معرفی میکند.با استفاده از این ویژگی برنامه نویسان قادر خواهند بود به صورت Inline انواع دلخواه خود را ایجاد کنند.به نمونه زیر توجه کنید:
کد ارائه شده، یک نوع بی نام را تعریف میکند که از طریق متغیر ضمنی محلی به نام anonymousType در اختیار قرار میگیرد.
چرا Anonymous types؟ انواع بی نام بهترین گزینه برای تولید Entity Typeها میباشند.همانطور که گفته شد Entity Typeها فقط حاوی دادهها هستند.بنابراین به بهترین نحو میتوان دادههای دریافت شده از کاربر را در انواع بی نام بسته بندی کرد.
نتیجه نوع متغیر محلی
کد بالا با کد زیر قابل تعویض میباشد:
این ویژگی تنها یک ntactic sugarراحت برای کوتاه تر بیان کردن متغیرهای محلی نمیباشد، بلکه برای تعریف متغیرهای بی نام لازم نیز است.
عبارات لامبدا :
عبارات لامبدا یک راه کوتاه برای نوشتن مقادیر توابع بی نام کلاس اول را فراهم میکنند. دو مثال زیر را در نظر بگیرید:
در مثالهای فوق، عبارات لامبدا صرفا یک نوع سینتکس برای delegateهای بی نام با مقادیر دارای بازگشت هستند.هر چند با توجه به نوع متن استفاده میشوند، کامپایلر #C میتواند لامبداها را به ASTها نیز تبدیل کند تا بعداً در زمان اجرا نیز بتوانند پردازش شوند.در مثال فوق، اگر listOfFoo یک مجموعه ساده داخل حافظه نباشد، ولی یک پوشه در اطراف جدول بانک اطلاعاتی میباشد. این تکنیک میتواند برای بهینه کردن اجرا، برای ترجمه بدنه لامبدا به عبارت معادل آن در SQL استفاده شود.در هر یک از دو راه فوق، خود عبارت لامبدا دقیقا شبیه کد به نظر میرسد، بنابراین روش استفاده در زمان اجرا، برای کاربر ناپیدا میباشد.
یکی از ویژگیهایی کهC# ۲.۰ ارائه کرد، توانایی تعریف توابع به صورت Inline بود که این ویژگی با عنوان توابع بی نام (anonymous methods) شناخته میشود. توابع بی نام در پارهای مواقع بسیار مفیدند. اما نحو(syntax) به کارگیری آنها دشوار میباشد. عبارات لامبدا ویژگی توابع بی نام را دارند اما با نحو ساده تری در C# ۳.۰معرفی شدهاند.به نمونه زیر توجه کنید:
تعریف عبارات لامبدا از نحو (syntax) خاصی پیرو میکند. همانطور که در کد بالا مشاهده میکنید، پارامترهای تابع هم به صورت صریح و هم به صورت ضمنی قابل بیان اند. کلمه return به صورت ضمنی حذف شدهاست. تابع معادل عبارت لامبدای اول به صورت زیر است:
لیست پارامترها و بدنه عبارت لامبدا توسط => از هم جدا میشوند. در صورتی که تعریف عبارت لامبدا بیشتر از یک خط کد باشد میتوان بدنه آن را با استفاده از {} نشان داد.
خواص خودکار
کامپایلر به طور خودکار یک متغیر نمونه خصوصی و قرار دهنده و قرار گیرنده مناسب تولید میکند، مانند :
توابع بسط داده شده
توابع بسط داده شده حالتی از سینتکس Suger هستند که امکان اضافه کردن متد جدید به کلاس موجود را بیرون از حوزه تعریف آن فراهم میکنند.در این مثال، تابع بسط داده شده یک تابع ایستا است که قابل فراخوانی توسط تابع مشابه میباشد.گیرنده فراخوانی مقید به اولین پارامتر تابع تحت عنوان this میباشد:
زبان سی شارپ کلمه کلیدی sealed را برای این منظور ارائه کرد که امکان ارث بری از یک کلاس را صلب کند. یعنی با اضافه شدن این کلمه کلیدی به ابتدای تعریف کلاس، امکان ارث بری از آن غیر ممکن میشود. C# ۳.۰ ویژگی جدیدی را در اختیار برنامه نویسان قرار میدهد به این صورت که میتوان هر نوع کلاسی حتی کلاسهای مهر شده با Sealed را با استفاده از Extension methodsبسط داد.
توابع جزئی
توابع جزئی به تولید کنندههای کد اجازه تولید اعلان توابع به صورت نقاط گسترش یافتهای که تنها شامل کدهای اصلی هستند را میدهد، در صورتی که یک نفر آن را در قسمتی از کلاسی دیگر اجرا کند.
متغیرهای ضمنی محلی :
C# 3.0 کلمه کلیدی جدید var را معرفی میکند که به کمک آن برنامه نویسان قادر خواهند بود متغیرهای محلی خود را بدون ذکر صریح نوع آنها، تعریف کنند.
یکی از ویژگیهای اصلی زبان سی شارپ،Strong Type بودن آن است. Strong Type بودن زبان به این معناست که با اعلان یک متغیر، نوع آن صریحا باید توسط برنامه نویس مشخص شود. آیا اضافه شدن این ویژگی جدید، منافاتی با Strong Type بودن این زبان دارد؟در پاسخ باید گفت که تعریف متغیرهای محلی به صورت ضمنی با استفاده از کلمه کلیدی var هیچ گونه منافاتی با Strong Type بودن سی شارپ ندارد. چون برنامه نویس میبایست نوع متغیر را به هنگام اعلان آن صریحا مشخص کند.نوع متغیر پس از اولین اعلان تا اتمام حوزه تعریف آن تغییر نخواهد کرد و هر گونه تلاش برای تغییر نوع با خطا مواجه خواهد شد.بنابراین دو اعلان زیر نامعبر هستند:
استفاده از var تنها در تعریف متغیرهای محلی امکانپذیر است. در اعلان متغیرها به صورت سراسری، پارامترهای توابع و مقادیر بازگشتی نمیتوان از var استفاده کرد. چرا var ؟ این ویژگی آزادی عملی بیشتری برای کار با متغیرهای محلی در اختیار برنامه نویس قرار میدهد. سناریویی را در نظر بیگیرید که یک تابع تحت شرایطی، مقادیر از انواع مختلف را برگرداند. در این صورت بدون درگیر شدن با casting و تبدیل نوع میتوان با تعریف متغیر ضمنی محلی هر نوعی را که تابع برمی گرداند، در اختیار داشت.
سازندههای پیشرفته : ماهیت تمامی برنامههای امروزی به گونهای ست که با حجم عظیمی از دادهها سرو کار دارند.برای مدیریت دادهها، نیاز به کلاسهایی ست که در مهندسی نرمافزار آنها را Entity Types مینامیم.این کلاسها به عنوان بستههایی از دادهها محسوب میشوند.معضل فعلی موجود در رابطه با Entity Typeها تعدد سازندههای آنها میباشد و ممکن است شما نیز با این مشکل برخورد کرده باشید.به این صورت که در سناریوهای مختلف، برنامه نویسان مجبور هستند سازنده یک کلاس را به چند شکل سربارگذاری کنند.C# ۳.۰ راه چارهای فوق العاده برای این مشکل ارائه میدهد. Object initializer حالت پیشرفتهای از سازنده میباشد.
این کلاس شامل سه متغیر بوده و برای هر متغیر خاصیتی تعریف شدهاست.اینک این سوالات مطرح میشوند : سازنده این کلاس را به چند شکل باید سربارگذاری کرد؟ سازندهای که هر سه متغیر را مقداردهی کند؟ شاید در مواردی هر سه متغیر در دست نباشد در این صورت چه سازندهای باید فراخوانی شود؟ C# ۳.۰ راه حل زیر را ارائه میدهد.فرض کنید بخوانیم نمونهای ازکلاس Person را ایجاد کنیم. همانطور که مشاهده میکنید، در C# ۳.۰ به هنگام نمونه سازی، این امکان در اختیار برنامه نویس قرار میگیرد که هر یک از خصیصههای موجود در کلاس را به دلخواه و بنا به نیاز مقدار دهی کند به صورت زیر :
عبارات جست و جو (Query Expression) : تیم طراح سی شارپ ویژگی فوق العادهای را به آن اضافه کرد که برنامه نویسان را قادر میسازد نحو (Syntax) زبانهای پرس و جو مانند SQL و XQuery را با استفاده از این زبان پیاده سازی کنند. این ویژگی با نام اختصاری LINQ شناخته میشود و دارای انواع زیر است:
نمونهای از کاربرد LINQ به صورت زیر است:
توضیح : در مثال بالا ابتدا یک آرایهٔ int با مقداردهی اولیه تعریف شدهاست.سپس با استفاده از دستورات) LINQ که جز کلمات کلیدی سی شارپ محسوب میشوند)، آرایهای با اعضای بزرگتر از ۵ انتخاب و در متغیر ضمنی محلی selective_array ذخیره میشود.در نهایت اعضای selective_array به صورت ۷ و ۹ و ۱۲ خواهد بود.در توضیح این ویژگی جدید به همین یک مثال بسنده میکنیم چون بیان تمامی جنبههای LINQ خود نیازمند نگارش مقالهای مفصل میباشد.
آرایههای نوع ضمنی :آرایهها را نیز میتوان با استفاده از کلمه کلیدی var تعریف کرد.
پیش پردازنده
ویژگی «دستورات پیش پردازنده» سی شارپ(اگرچه آنها به واقع یک پیش پردازنده نیستند) مبنی بر دستورات پیش پردازنده C است که به برنامه نویس اجازه تعریف سمبلهایی را میدهند.برخی از این دستورات عبارتند از : #if ، #region ، #define . راهنماهایی نظیر #region تذکراتی به ویرایش گرها برای code foldingمی دهند.
توضیحات کد
توضیحات تک خط با استفاده از دو اسلش تعریف میشوند(//) و توضیحات چند خطی با /* شروع و به */ ختم میشوند.
توضیحات چند خطی هم چنین میتوانند با /* شروع و با */ تمام شوند.
این ورژن در تاریخ ۱۹ نوامبر سال ۲۰۰۷ به عنوان بخشی از .NET Framework ۳.۵ عرضه شد.که شامل ویژگیهای جدید الهام شده از زبانهای برنامه نویسی اصلی(Functional) مانند Haskell و ML، و الگوی LINQ برای CLR است.در حال حاظر توسط هیچ موسسه استاندارد سازی ای تائید نشدهاست.
معرفی (Language-Integrated Query(LINQ
LINQ، یک زبان پرس و جوی قابل انعطاف و همه منظوره برای بسیاری از انواع منبع داده هااست( مثل انتخاب اشیا شناور، سندهای XML، بانکهای اطلاعاتی و . . .) که در ویژگیهای ۳#C جمع شدهاند. سینتکس زبان به زحمت از 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" };
C# ۲.۰توابع بی نام را معرفی کرد. C# ۳.۰هم انواع بی نام را معرفی میکند.با استفاده از این ویژگی برنامه نویسان قادر خواهند بود به صورت 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>>();
عبارات لامبدا :
عبارات لامبدا یک راه کوتاه برای نوشتن مقادیر توابع بی نام کلاس اول را فراهم میکنند. دو مثال زیر را در نظر بگیرید:
کد:
listOfFoo.Where(delegate(Foo x) { return x.Size > 10; })
listOfFoo.Where(x => x.Size > 10);
یکی از ویژگیهایی کهC# ۲.۰ ارائه کرد، توانایی تعریف توابع به صورت Inline بود که این ویژگی با عنوان توابع بی نام (anonymous methods) شناخته میشود. توابع بی نام در پارهای مواقع بسیار مفیدند. اما نحو(syntax) به کارگیری آنها دشوار میباشد. عبارات لامبدا ویژگی توابع بی نام را دارند اما با نحو ساده تری در C# ۳.۰معرفی شدهاند.به نمونه زیر توجه کنید:
کد:
static void Main(string[] args)
{
(int x) => x + 1; // explicitly typed parameter
(y, z) => y * z; // implicitly typed parameter
}
کد:
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);
توابع جزئی
توابع جزئی به تولید کنندههای کد اجازه تولید اعلان توابع به صورت نقاط گسترش یافتهای که تنها شامل کدهای اصلی هستند را میدهد، در صورتی که یک نفر آن را در قسمتی از کلاسی دیگر اجرا کند.
متغیرهای ضمنی محلی :
C# 3.0 کلمه کلیدی جدید 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ها تعدد سازندههای آنها میباشد و ممکن است شما نیز با این مشکل برخورد کرده باشید.به این صورت که در سناریوهای مختلف، برنامه نویسان مجبور هستند سازنده یک کلاس را به چند شکل سربارگذاری کنند.C# ۳.۰ راه چارهای فوق العاده برای این مشکل ارائه میدهد. 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; }
}
}
این کلاس شامل سه متغیر بوده و برای هر متغیر خاصیتی تعریف شدهاست.اینک این سوالات مطرح میشوند : سازنده این کلاس را به چند شکل باید سربارگذاری کرد؟ سازندهای که هر سه متغیر را مقداردهی کند؟ شاید در مواردی هر سه متغیر در دست نباشد در این صورت چه سازندهای باید فراخوانی شود؟ C# ۳.۰ راه حل زیر را ارائه میدهد.فرض کنید بخوانیم نمونهای ازکلاس Person را ایجاد کنیم. همانطور که مشاهده میکنید، در C# ۳.۰ به هنگام نمونه سازی، این امکان در اختیار برنامه نویس قرار میگیرد که هر یک از خصیصههای موجود در کلاس را به دلخواه و بنا به نیاز مقدار دهی کند به صورت زیر :
کد:
Person person = new Person
{
Age = 21,
FirstName = «Mohamad Sadegh»,
LastName = "Mozafari"
};
کد:
§ 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 ۳.۰
کد:
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 > 0 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) {}
}
گروه دور همی پارسی کدرز
https://t.me/joinchat/GxVRww3ykLynHFsdCvb7eg
https://t.me/joinchat/GxVRww3ykLynHFsdCvb7eg