۱۳۸۹ يکشنبه ۱۰ مرداد Skip Navigation Links
صفحه اصلی
مقالاتExpand مقالات
تازه هاExpand تازه ها
کتاب ها
فروشگاه
اعضا
فروم (سؤال و جواب)
PD on Facebook
 
 
 
کلمه عبور خود را فراموش کرده اید؟
 
 
 C# 4.0، نگاهي به آينده - قسمت سوم
.NET C#
تاریخ ثبت:  ۸۷/۱۰/۱
تعداد نمایش:  ۲۳۹۵
  نویسنده: ابوالفضل حسن الدينف
 
   ۱۲  نفر تا این لحظه به این مقاله امتیاز داده اند.
 
   Bookmark and Share

در مقالات قبلي از سري C# 4.0، نگاهي به آينده  پيرامون ويژگي آرگومان هاي اختياري - نامي و واريانس بحث كرديم. در اين مقاله و مقاله بعدي ، برنامه نويسي پويا، بارزترين و جديدترين ويژگي C# 4.0 را معرفي خواهيم كرد.

توجه داشته باشيد كه تمام تكنولوژي فعلي در حال توسعه و تكامل مي باشد و يكي از دلايلي كه مايكروسافت CTP آن را در اختيار عموم قرار داده است، دريافت نظرات و فيدبك هاي بيشتر به منظور ارائه جامع محصول نهايي مي باشد. آنچه كه در سري مقالات C# 4.0، نگاهي به آينده ارائه  مي شود، بر پايه نسخه اوليه بوده و نام برگزيده شده براي اين سري گوياي اين امر است.

برنامه نويسي پويا

برنامه نويسي پويا بحث داغ دات نت فريم ورك 4.0 مي باشد. طراحان و توسعه دهندگان اين كتابخانه عظيم در صدد هستند تا با فراهم كردن بستر مناسب، امكان فراخواني هاي پويا را براي زبان هاي تحت دات نت از جمله سي شارپ فراهم كنند. اين وظيفه را Dynamic Language Runtime و به اختصار DLR در محيط فريم ورك فراهم خواهد كرد.

برنامه نويسي پويا مربوط به زمان اجرا (Run Time) بوده كه نقطه مقابل زمان كامپايل مي باشد (Compile Time). در زمان كامپايل سه عمل زير انجام مي شود:

  • تحليل لغوي: در اين مرحله كد نوشته شده به سمبل ها، كلمات و اعداد شكسته مي شود. كامپايلر بر اساس نحو (syntax) زبان، كد را بررسي كرده، در صورت برخورد با خطاي لغوي -  مثل جا انداختن نقطه ويرگول در پايان عبارت - پيغام خطاي مناسب را نمايش خواهد داد.

  • تحليل معنايي: در اين مرحله عبارات به دست آمده از مرحله قبل از نظر معنايي مورد ارزيابي كامپايلر قرار مي گيرند. به عنوان مثال حاصلضرب دو مقدار اعشاري را نمي توان در يك مقدار صحيح قرار داد و با وجود اينكه از نظر لغوي عبارت مذكور درست است كامپايلر خطاي معنايي را نمايش خواهد داد.

  • توليد كد ماشين: در اين مرحله در صورت عدم وجود خطا، كد ماشين معادل، توليد شده و در يك پيمانه اجرايي (فايل exe) يا كتابخانه (فايل dll) ذخيره مي شود.

كامپايلرهاي مختلف ممكن است عمليات بيشتري علاوه بر آنچه كه بيان شد، در زمان كامپايل انجام دهند كه مرحله لينك نمونه اي از اين مراحل مي باشد. 

تمامي زبان هاي دات نت در مرحله توليد كد ماشين، به زبان مياني مايكروسافت (MSIL) ترجمه شده و در فايل اسمبلي اعم از فايل اجرايي يا كتابخانه اي ذخيره مي شوند. از اين رو هنگام اجراي فايل اسمبلي در محيط CLR، كامپايلري تحت عنوان Just In Time Compiler زبان مياني مايكروسافت را به زبان ماشين ترجمه مي كند.

افزودن ويژگي پويا به كامپايلر زبان برنامه نويسي اين امكان را فراهم مي كند كه كامپايلر از تحليل معنايي تعاريف و بلوك هاي پويا صرف نظر كند. از اين رو تحليل معنايي به زمان اجرا موكول مي شود و اگر خطايي در معناي تعاريف يا بلوك هاي پويا وجود داشته باشد، پيغام خطاي زمان اجرا صادر خواهد شد. 

نوع جديد dynamic در سي شارپ

در سي شارپ 4.0 برنامه نويسي پويا از طريق نوع جديد گنجانده شده در زبان يعني dynamic امكان پذير خواهد بود. كلمه كليدي dynamic در تمامي جاهايي كه امكان تعريف و استفاده از نوع وجود دارد، قابل استفاده مي باشد. به نمونه كد زير توجه كنيد:

dynamic d = GetDynamicObject();
d.M(7);

كامپايلر سي شارپ اجازه خواهد داد كه توابعي با نام و آرگومان هاي دلخواه بر روي d فراخواني شوند. چون d از نوع پويا است كامپايلر هيچ تفسير معنايي از فراخواني(M(7 نخواهد داشت و تفسير آن را به زمان اجرا موكول خواهد كرد.

علاوه بر تابع، فراخواني عضو، خصيصه، عمليات انديس، عملگر و نماينده بر روي نوع پويا امكان پذير خواهد بود.

d.f = d.P; // getting and settings fields and properties
d["one"] = d["two"]; // getting and setting through indexers
int i = d + 3; // calling operators
string s = d(5,7); // invoking as a delegate

تنها نقش كامپايلر سي شارپ در زمان كامپايل اين سناريو ، بسته بندي اطلاعاتي است كه بيان مي كنند "چه اتفاقي براي d رخ داده است". در زمان اجرا تفسير دقيق هر يك از اين فراخواني ها مشخص خواهد شد.

تفسير نوع پويا در زمان اجرا

در مثال قبل با تعريف نوع پويا d، اين امكان را فراهم كرديم كه كامپايلر به بسته بندي اطلاعات موجود در زمينه فراخواني ها و عمليات انجام شده بر روي d اكتفا كند تا در زمان اجرا تفسير واقعي اين اطلاعات به دست آيد. اين تكنيك اصطلاحا پيگرد پويا (dynamic lookup) ناميده مي شود.

در زمان اجرا، ذات d نوع تفسير ها را مشخص خواهد كرد. d مي تواند يكي از انواع پويا زير باشد:

  • شيئي از نوع COM:  چنانچه d شيئي از نوع COM باشد، DLR، تفسير پويا آن را از طريق واسط IDispatch كه نوع COM فراهم مي كند، انجام خواهد داد. فراخواني پويا شيء COM، امكان استفاده از ويژگي هاي COM را كه نقطه مقابلي در زبان سي شارپ ندارند،  فراهم خواهد كرد. خصيصه هاي انديس دار (indexed properties) و خصيصه هاي پيش فرض (default properties) نمونه اي از اين ويژگي ها  هستند .

  • شيء پويا (Dynamic Object): اگر d واسط IDynamicObject را پياده سازي كند، از نوع پويا محسوب خواهد شد. پياده سازي واسط IDynamicObject، اين امكان را فراهم مي كند كه نوع جديد تمامي عمليات پويا را به دلخواه خود سربارگذاري كند. اين ويژگي براي توسعه زبان هاي پويا مانند IronPython و IronRuby در توصيف مدل پويا آبجكت ها مورد استفاده قرار مي گيرد. براي استفاده از API به كار رفته در مدل HTML DOM و دسترسي به خصيصه هاي آبجكت هاي آن نيز از اين روش استفاده خواهد شد.

  • شيء ساده (Plain Object): چنانچه d هيچ يك از دو نوع بالا نباشد، مي توان نتيجه گرفت كه d شيء استاندارد دات نت بوده كه تفسير پويا آن از طريق Reflection و Runtime Binder سي شارپ انجام خواهد شد. اين بخش از كامپايلر سي شارپ به عنوان مؤلفه در زمان اجرا براي "اتمام پردازش نوع پويا" مورد استفاده قرار مي گيرد.

موارد استفاده از ويژگي پويا

با توجه به انواع اشياء پويا مي توان به سه سناريوي زير كه بيشترين بهره را از ويژگي پويا خواهند برد، اشاره كرد:

  • اتوماسيون آفيس و ديگر اينتراپت هاي COM: ويژگي پويا باعث خواهد شد كه نسخه بعدي اتوماسيون آفيس ساده تر از قبل شود. از اين رو نيازي به استفاده از تايپ هاي بزرگ و فراخواني توابع با آرگومان هاي زياد وجود نخواهد داشت.

  • استفاده از زبان هاي پويا ديگر:  محبوبيت زبان هاي پويا از قبيل IronPython و IronRuby رو به افزايش است. در حال حاضر اين زبان ها به راحتي مي توانند از كدهاي سي شارپ و ديگر زبان هاي دات نت بهره مند شوند در حاليكه عكس آن امكان پذير نيست. فعال شدن ويژگي پويا باعث خواهد شد كه فراخواني اشياء زبان هاي پويا و ساختارهاي متغيير مانند HTML DOM در زبان هاي دات نت فراهم شود. توسعه دهندگان قادر خواهند بود ضمن استفاده از كدهاي موجود، به توسعه ي آن ها و توليد كدهاي جديد بپردازند.

  • فراخواني راحت تر Reflection: در حال حاضر توسعه دهندگان و برنامه نويسان از طريق فضاي نام Reflection قادر به توليد كلاس ها و فراخواني توابعي هستند كه در زمان كامپايل نامشخص اند. ويژگي پويا كامپايلر سي شارپ چنين فراخواني هايي را به مراتب ساده تر خواهد كرد.

توسعه  آبجكت هاي پويا

همانطور كه اشاره شد، واسط IDynamicObject امكان تعريف نوع پويا با رفتار دلخواه را فراهم مي كند. IDynamicObject براي توصيف رفتار پويا خود، از كلاسي به نام MetaObject استفاده مي كند. از طريق سربارگذاري توابع زير كه توسط MetaObject ارائه مي شوند، تفسير پويا فراخواني ها در زمان اجرا مشخص مي شود:

همانطور كه مشاهده مي شود، هر تابع بيانگر يك عمل انجام شده بر روي نوع پويا است. به عنوان مثال تابع Call براي سربارگذاري نحوه فراخواني توابع بر روي آبجكت پويا به كار مي رود. توابع GetMember و SetMember براي سربارگذاري نحوه فراخواني خصيصه بر روي نوع پويا استفاده مي شوند. تمامي توابع، دو آرگومان استاندارد در ليست پارامترهاي خود دارند. پارامتر اول از نوع نماينده بوده كه اطلاعاتي پيرامون نوع عمل انجام يافته بر روي نوع پويا را شامل مي شود. پارامتر دوم نيز آرايه اي از  آرگومان هاي عمل صورت گرفته بر روي نوع پويا مي باشد. به عنوان مثال اگر تابعي بر روي نوع پويا با يك پارامتر فراخواني شده باشد، نماينده حاوي تابع و آرايه حاوي پارامتر اين تابع خواهد بود.

نسخه CTP به صورت كامل و نهايي از ويژگي هاي پويا معرفي شده در اين مقاله پشتيباني نمي كند. همانطور كه در ليست توابع ارائه شده براي سربارگذاري مشاهده مي شود، توابع مربوط به سربارگذاري indexor و delegate گنجانده نشده اند.

در ادامه مثال ساده اي براي مرور مفاهيم بيان شده در اين مقاله معرفي مي كنيم. نوع پويا PdDynamicType را به شكل زير تعريف كرده ايم :

 تابع Call را سربارگذاري كرديم تا Runtime Binder در زمان اجرا با برخورد به فراخواني تابع دلخواه بر نوع PdDynamicType نام آن را در كنسول چاپ كند. علاوه بر تعريف نوع پويا، نوع ساده PdType به شكل زير تعريف شده است:

در نهايت تعاريف بالا به شكل زير در تابع Main به كار رفته اند:

تابع  PdDynamicCall سه بار و هر بار با نوعي متفاوب فراخواني شده است. اين تابع نوع پويا dynamicType را به عنوان آْرگومان دريافت  كرده و تابعي به نام PdFunc را بر روي آن فراخواني مي كند. در زمان كامپايل، تنها اطلاعي كه كامپايلر سي شارپ از dynamicType دارد اين است كه تابع PdFunc بر روي آن فراخواني شده است و اينكه اين تابع چيست و چه كاري انجام مي دهد، تنها در زمان اجرا مشخص خواهد شد. به خروجي حاصل از اين اجرا توجه كنيد:

همانطور كه مشاهده مي شود در زمان اجرا، تابع PdFunc نوع int پيدا نشده است و لذا استثناي زمان اجرا نمايش داده شده است. به همين دليل است كه كد تابع PdDynamicCall داخل بلوك try - catch نوشته شده است. PdType تعريفي براي تابع PdFunc ارائه كرده است. فراخواني آن در زمان اجرا منجر به چاپ خط دوم در كنسول شده است. در نهايت فراخواني PdFunc بر روي نوع پويا PdDynamicType صورت گرفته است كه سربارگذاري تابع Call، باعث چاپ نام تابع در خط سوم كنسول شده است.

كلام آخر

در مقاله بعدي به بحث و بررسي بيشتر پيرامون نوع پويا C# 4.0 خواهيم پرداخت.

به اطلاع علاقمندان مي رساند كه سفارش CTP Visual Studio 2010 براي اجراي كدهاي ارائه شده در اين مقاله و كار با C# 4.0 از طريق فروشگاه وب سايت امكانپذير مي باشد.

در پايان اين مقاله تقاضا داريم كه با انعكاس نظر خود در بخش پيام در ارائه بهتر كمي و كيفي مقالات آينده ما را همراهي كنيد. پيشاپيش از نظرات و انتقادات شما سپاسگزارم.

هر گونه استفاده از مطالب اين مقاله تنها با كسب اجازه از نويسنده مقاله مجاز مي باشد. اين مقاله به صورت اختصاصي در وب سايت Persia Developers ارائه شده است.

  کیفیت مقاله ارائه شده از نظر شما   
برای دادن رتبه به این مقاله می بایست Login کرده باشید.
  درباره نویسنده
ابوالفضل حسن الدينف
Member of Barid Development Team,EOrg & ERP Solutions
همه مقاله های نوشته شده توسط این کاربر (۱۱)
 
  پیام جدید
صفحه ۱ - پیامهای اصلی ۱ تا ۲ از مجموع ۲ پیام اصلی
اولین قبلی بعدی

 عنوان فرستنده تاریخ
 
ممنون از مقاله کاوش حسینی ۸۷/۱۰/۷
 
مثل همیشه کامل فربد صالحی ۸۷/۱۰/۳
پاسخ به: مثل همیشه کامل ابوالفضل حسن الدينف ۸۷/۱۰/۳
منظورم این بود که.. فربد صالحی ۸۷/۱۰/۳
منظورم این بود که.. ابوالفضل حسن الدينف ۸۷/۱۰/۳
اولین قبلی بعدی

Copyright © 2006 - 2010 All Rights Reserved.
Please direct your questions or comments to