PDA

View Full Version : مقاله: ویژگی های C# 4.0



Mehdi Asgari
یک شنبه 12 آبان 1387, 01:21 صبح
سلام
{مدیر محترم بخش: اگه تشخیص می دید که بهتره این مقاله به بخش مقاله های سایت منتقل بشه ، لطفا این کارو بکنید.}
ویژگی های نسخه ی 4.0 زبان سی شارپ:
C# 4.0 پنجمین رلیز از زبان برنامه نویسی سی شارپه (1.0 , 1.1, 2.0, 3.0) که قراره همراه با Visual Studio 2010 و .NET Framework 4.0 عرضه بشه.
در حال حاضر تنها منابع موجود برای یادگیری بیشتر دربارۀ این زبان ، صحبت های (http://mschnlnine.vo.llnwd.net/d1/pdc08/WMV-HQ/TL16.wmv) آقای Anders Hejlsberg (http://en.wikipedia.org/wiki/Anders_Hejlsberg) (خالق زبان سی شارپ) در PDC 2008 ، یک داکیومنت از مایکروسافت (http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=csharpfuture&DownloadId=3550) و نسخه ی CTP ویژال استودیو 2010 (http://www.barnamenevis.org/forum/showthread.php?t=129017) هستن.
مهم ترین ویژگی C# 4.0 قابلیت برنامه نویسی پویا یا Dynamic programming (http://en.wikipedia.org/wiki/Dynamic_programming_language) هست. یک نوع دادۀ dynamic نوع داده ای هست که هنگام کامپایل برنامه اطلاعاتی در مورد ساختار و عملیات موجود در اون نداریم. سه کاربرد مهم این ویژگی ، ارتباط با زبان های دینامیک (مثل IronPython (http://www.codeplex.com/Wiki/View.aspx?ProjectName=IronPython)و IronRuby (http://www.ironruby.net/)) ، ارتباط با COM و دسترسی به اشیای .NET از طریق Reflection هست.
(پاراگراف قبل به این معنی نیست که C# یک زبان دینامیکه. سی شارپ یک زبان استاتیک هست ، فقط می تونه با زبان های دینامیک ارتباط برقرار کنه ،همونطور که در نسخه ی 3 قادر بود construct هایی اززبان های تابعی رو پشتیبانی می کرد ، اما یک زبان تابعی نبود)
ویژگی های مهم جدید C# 4.0 : (فقط عنوان – مثال ها در ادامه اومدن)
• برنامه نویسی پویا: دسترسی به متد ، عملگر ، پراپرتی و فیلد هایی که در زمان کامپایل مشخص نیستن و نوعشون در زمان اجرا مشخص میشه
• پارامترهای اختیاری و با نام: پارامترهای اختیاری رو برنامه نویسای VB و C++ باهاش آشنا هستن. اختیاری یعنی این که می تونیم اون رو مشخص نکنیم ، در این صورت مقدار پیش فرض اون پارامتر جایگزین خواهد شد. فراخوانی پارامتر با نام هم یعنی می تونیم تابع رو به ترتیب تعریف پارامترهاش ، با مقادیر مربوطه فراخوانی نکنیم و اونا رو پس و پیش بنویسیم ، منتها با ذکر اسمشون.
• ویژگی های مختص COM : دو ویژگی قبلی خیلی در ارتباط با دنیای COM کمک می کنن ، غیر از اون ها ویژگی های کوچک دیگری هم هستن که کار با COM رو راحت تر می کنن.
• واریانس: در گذشته (البته یعنی الان!) یک IEnumerable<string> با یک IEnumerable<object> برابر نبود. در نسخه ی بعدی سی شارپ این رویه عوض خواهد شد.
برنامه نویسی پویا:
یعنی توانایی فراخوانی متد ها و دسترسی به اشیا به صورت پویا. (کامپایلر تابعی رو که فراخوانی میشه نمی شناسه و نمی تونه اون رو resolve کنه. موقع اجرا معلوم میشه مقدار اون متد/شی/فیلد/... چی بوده) (late binding (http://en.wikipedia.org/wiki/Dynamic_binding))
مثال:


dynamic d = GetDynamicObject(…);
d.F(10);

در این مثال ما نمی دونیم d از چه نوعی هست ، فقط میخوایم در زمان اجرا متد F اون با یک پارامتر از نوع int و با مقدار 10 فراخوانی بشه.
مثال های بیشتر:


dynamic d = GetDynamicObject(..);
d.f = d. P; //getting and setting fields and properties
d[“one”] = d[“two”] ;// getting and setting through indexers
int I = d + 9; //calling operators
string s = d(6,9); //invoking as a delegate

اگه d یک شی COM باشه ، عملیات (مثلا فراخوانی متد) از طریق IDispatch (http://en.wikipedia.org/wiki/IDispatch)انجام میشه.
(در صورت پیدا نشدن یکی از ساختار های زبانی فوق ، یک runtime exception اتفاق می افته.)
(در واقع اون زیر ساختاری که چنین امکانی رو به ما میده ، DLR (http://en.wikipedia.org/wiki/Dynamic_Language_Runtime)یا Dynamic Language Runtime هست که در .NET 4.0 معرفی شده و پیاده سازی زبان هایی مثل IronPython و IronRuby بر اساس اون هست)
محدودیت ها: از این طریق قادر به فراخوانی extension method (http://en.wikipedia.org/wiki/Extension_method) ها نخواهیم بود. همچنین anonymous method (http://msdn.microsoft.com/en-us/library/0yw3tz5k(VS.80).aspx) ها رو نمی تونیم به عنوان پارامتر به یک فراخوانی پویا ارسال کنیم.
پارامترهای اختیاری و با نام: سهولت بزرگی که این دو ویژگی برای ما به ارمغان می یارن ، کار با بعضی اشیای COM هست (مثل API های Office)
مثال:


public void F(int i, int j = 4, int k = 9);

در این مثال پارامترهای j و k اختیاری هستن و می تونیم موقع فراخوانی تابع F اون ها رو حذف کنیم.
مثال:


F(1,2,3);
F(1,2);
F(1);

خط اول که واضحه. در خط دوم ما مقدار k رو نمی دیم ، پس همون مقداز پیش فرض خودش (9) رو خواهد داشت. خط سوم هم همینطور.
حالا چطور می تونیم پارامترها رو با نام مقداردهی کنیم ؟


F(1,k:3);
F(i:1,k:3);
F(k:3,i:1);

ویژگی های مختص COM:
بسیاری از متدهای COM نوع variant (http://en.wikipedia.org/wiki/Variant_type)رو برمی گردونن (یا به عنوان پارامتر می گیرن) (که ما به نام object می شناسیمشون). معمولا ما می دونیم نوع برگشتی فلان تابع چیه ، ولی باز مجبوریم cast کنیم. این مشکل(؟) در C# 4.0 به این شکل برطرف شده:
به جای


Execl.Range range = (Excel.Range)excel.Cells[1,1];

می گیم:


Excel.Range range = excel.Cells[1,1];

در بعضی از API های COM کلی پارامتر از نوع ارجاع (reference) داریم که معمولا تغییری هم در اون متغیر ارسال شده نمی دن و فقط برای ارسال یه مقدار هستن. برنامه نویس C# مجبوره کلی متغیر تعریف کنه و ارسال کنه به این تابع بدون این که ازشون استفاده ای کنه. در نسخه ی جدید می تونیم این نوع متغیر ها رو تعریف نکرده و فقط مقدار مورد نیاز رو به عنوان پارامتر به تابع بدیم ؛بقیۀ کار ها رو خود کامپایلر انجام میده (ایجاد متغیر های temp که به اون مقادیر اشاره می کنن و پس از فراخوانی تابع ، پاک میشن)
واریانس
یکی از مشکلات عجیب generics اینه که کد زیر اشتباهه:


IList<string> strings = new List<string>();
IList<object> objects = strings;

البته یه دلیل موجه داره و اونم مشکلاتیه که مثلا کد زیر به وجود می یاره:


objects[0] = 7;
string s = strings[0];

اما مواقعی هم هست که امکان وقوع همچین مشکلی وجود نداره ، مثل:


IEnumerable<object> objects = strings;

واریانس به ما اجازه میده که همچین انتساب هایی رو در کدمون داشته باشیم. (البته اگه safe باشن)
Covariance:
در .NET 4.0 اینترفیس IEnumerable<T> به شکل زیر خواهد بود:


public interface IEnumerable<out T> : IEnumerable
{
IEnumerator<T> GetEnumerator();
}
public interface IEnumerator<out T> : IEnumerator
{
bool MoveNext();
T Current {get; }
}

شاید استفاده از out کمی محدود کننده باشه ، اما در عوض اینترفیس در T کوواریانت میشه ، یعنی اگه بین A و B یک تبدیل موجود باشه ، اون وقت IEnumerable<A> از نوع IEnumerable<B> در نظر گرفته میشه. اون وقت ، هر زنجیره ای از رشته ها ، زنجیره ای از object هم خواهند بود. این ، در بسیاری از متدهای LINQ به درد می خورده. مثال:
var result = strings.Union(objects);
Contravariance
پارامترهای نوع (Type Parameters) (همونT معروف) می تونن یه پیرایندۀ in هم داشته باشن که اون ها رو محدود کنه به یه پارامتر ورودی (برای modifier نتونستم ترجمه ای بهتر از پیراینده پیدا کنم)


public interface IComparer<in T>
{
public int Compare(T left, T right);
}

در نتیجه یک IComparer<object> ، یک IComparer<string> هم خواهد بود. (اگه یه comparer بتونه هر دو objectی رو مقایسه کنه ، قاعدتا باید بتونه همین کارو برای هر دو stringی هم بکنه. به این میگن contravariance)
یک نوع generic میتونه هم پیرایندۀ in داشته باشه و هم out. مثل Func (http://msdn.microsoft.com/en-us/library/bb534960.aspx)<> :
public delegate TResult Func<in TArg, out TResult>(TArg,arg);
(پس ، یه Func<object,string> میتونه به جای یک Func<string,object> به کار برده بشه.

منبع اصلی: http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=csharpfuture&DownloadId=3550
(بقیۀ منابع به صورت لینک در این نوشته اومدن)

vcldeveloper
یک شنبه 12 آبان 1387, 02:16 صبح
یعنی اصلی ترین قابلیت هاش از نسخه 3.0 به 4.0 همین ها هستند؟!!
پارامترهای اختیاری که از سال ها قبل در سایر زبان ها وجود داشتند. تعجب می کنم که چطور هلزبرگ که از تیم دلفی به مایکروسافت اومد، اینقدر دیر این قابلیت را که سال ها در Turbo Pascal و دلفی وجود داشت را به #C آورد.

متوجه جالب توجه بودن Dynamic Programming هم نمیشم! این مثال هایی که اینجا زده شده، همه اش را میشه با هر زبانی که از COM پشتیبانی میکنه انجام داد، فقط اونجا از نوع داده Variant استفاده میشد، اینجا شده dynamic. این مدل late-binding خیلی هم جالب نیست؛ از یک طرف کارایی آن از early-binding کمتر هست، از یک طرف هم در هنگام نوشتن کد مشکل type-safety داره، همونطور که در COM هم بود، و با استفاده از Type Library حل میشد؛ یعنی برنامه نویس که مینویسه d.DoSomething، تا زمانی که برنامه اجرا نشه، و کد d.DoSomething اجرا نشه، نمیشه فهمید که آیا کد درست نوشته شده یا نه. این کار دیباگ کردن را مشکل تر میکنه. در هر حال، اگر قابلیت dynamic programming همین هست، با توجه به اینکه #C قبل از این هم از COM پشتیبانی می کرد، نباید اصلا چیز جدیدی باشه.

Mehdi Asgari
یک شنبه 12 آبان 1387, 03:01 صبح
یعنی اصلی ترین قابلیت هاش از نسخه 3.0 به 4.0 همین ها هستند؟!!
به نظر من ویژگی بزرگ و قابل تحسینی نداره (بر خلاف نسخه های قبلی: Generics ، LINQ ، anonymous methods)
طراحان C# قبلاها در مورد default parameters گفته بودن: http://blogs.msdn.com/csharpfaq/archive/2004/03/07/85556.aspx
در کل من ویژگی خفنی در C# 4.0 نمی بینم (لااقل برای کار خودم) و فکر می کنم فقط بحث سهولت کدنویسی بوده که باعث شده اینا به زبان اضافه بشن و به نظر من بهای سنگینی پرداخته شد (بزرگ تر شدن زبان)