صفحه شخصی سید علا سبزپوش

برنامه نویس دات نت و sql_server --ریاضیات

صفحه شخصی سید علا سبزپوش

برنامه نویس دات نت و sql_server --ریاضیات

Anonymous Methods

در پست قبلی در مورد delegate  صحبت کردیم ، اگر دقت کنید delegate  ابتدا می بایست توسط یک متد با نام اعلان می شد و سپس بر اساس همان متدی با امضای یکسان ، لیستی از متدهای دیگر به آن اضافه می شد .

اما در ‎ سی شارپ 2 شما می توانید delegate مورد نظر را در بدنه ی کد خود و بدون نیاز به تعریف متد مجزا اعلان کنید . در واقع اینجا ما با متدهایی سرو کار خواهیم داشت که بی نام هستند . در واقع می توان گفت استفاده از متدهای بی نام ، به نوعی کد نویسی را کاهش می دهد. ما در هر جا که لازم داشتیم می توانیم فورا یک متد بی نام استفاده کنیم .





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

برای درک بهتر مطلب خواندن لینکهای زیر بسیار مفید هستند .




http://www.codeproject.com/KB/cs/InsideAnonymousMethods.aspx


http://msdn.microsoft.com/en-us/library/0yw3tz5k.aspx



Delegates چیست ؟

Delegates  می تواند شی باشد  که شامل لیستی از متدهای یکسان (هم امضا و دارای مقادیر بازگشتی یکسان )

 

تعریف متدهای یکسان و هم امضا : به متدهایی گفته می شود که دارای ساختار یکسان باشند یعنی تعداد و مقادیر و نوع  پارامترها ورودی و خروجی یکسان است .

 

وقتی یک delegates  فراخوانی میشود ، تمام متدهای آن نیز فراخوانده می شوند . مانند شکل زیر :



به لیست متدها invocation list  می گوییم . پس هر وقت نام این اصطلاح را شنیدیم باید بدانیم که منظور لیست متدهای موجود در delegates  است .

این متدها می توانند از هر کلاس یا ساختار باشند . تنها نکته مهم در مورد آنها این است که باید هم امضا و یکسان باشند .ما در واقع یک لیستی ایجاد می کنیم که دارای ساختاری منسجم و سپس تمام متدهایی  که دارای همان ساختار هستند را در این لیست قرار می دهیم . تا در نهایت بتوانیم همه این متدها را یکجا فراخوانی کنیم .

 

فرم کلی تعریف delegate

Delegate     نام      مقدار بازگشتی  delegate (پارامترها)

 

مثلا :

delegate void MyDel ( int x );

 

در تعریف مثال بالا ما یک delegate  تعریف کردیم که می تواند متدهایی را بپذیرد که هیچ مقدار برگشتی ندارند و در مقابل پارامتر ورودی از نوع عدد صحیح دارند. نام این          delegate  برابر با mydel   است . تعریف بالا صرفا یک اعلان ازنوع delegate است .

شما باید تفاوت بین اعلان از نوع delegate  و شی یا object  از نوع delegate را بدانید .

وقتی ما delegate را اعلان می کنیم . در حقیقت ما یک لیست را قانون مندی را تعریف می کنیم که اشیا باید با همان قانون و فرم در آن قرار بگیرند . شکل زیر مبین همین تفاوت است .


حال اگر دقت کنید تعریف delegate بسیار شبیه به تعریف یک متد است با این تفاوت که :

تعریف delegate باید حتما با واژه اصلی و کلیدی delegate همراه باشد

در تعریف delegate ، متد های ما دارای بدنه نیستند . و فقط اعلان می شوند.

 

 

تعریف شی delegate

 

بعد از آنکه ما شیی از نوع delegate تعریف کردیم برای استفاده از delegate در برنامه باید شیی از نوع delegate تعریف کنیم . اما قبل از تعریف شی ما باید حداقل یک متد با ساختار متد delegate  داشته باشیم . تا بتوانیم آن را در لیست delegate قرار دهیم .

 

مثلا برای delegate مثال بالا ، باید متدی داشته باشیم با همان فرم


private void myMethod (int i)

{

//  method body

}

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

 

Mydel  Delvar = new mydel(mymethod);

 

همانطور که می بینید ما یک متد با همان ساختار delegate به لیست invocation list اضافه کردیم .

اما همانطور که در ابتدا گفتم ، ما به لیست invocation list می توانیم چندین متد اضافه کنیم یا حذف کنیم .

 

اضافه کردن متدها به invocation list بسیار ساده است فرض کنید متدی دیگر با همان فرم delegate  داریم .


private void myMethod۲ (int i)

{

//  method body

}

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

 

 

Delvar +=new mydel(mymethod2);

 

 

ترتیب متدها در delegate  را در شکل زیر مشاهده کنید :

و سرانجام برای حذف متدی از لیست delegate  بصورت زیر عمل می کنیم .

 

Delvar - =new mydel(mymethod2);

 

با دستور زیر متد از لیست خارج می شود .

 

حال اگر آبجکت delegate مورد نظر را فراخوانی  کنیم، تمام متدهایی که در Invocation List آن موجود هستند اجرا میشوند، نحوه فراخوانی  کردن یک آبجکت delegate مانند فراخوانی یک متد و ارسال پارامتر (در صورت نیاز) به آن میباشد :

مثال زیر را :

Delvar(55);

با استفاده از دستور بالا عدد 55 به عنوان پارامتر به تمام متدها ارسال می شود وتمام متدهای موجود در Invocation List به ترتیب قرار گرفتن در لیست Invocation List اجرا می شوند .

 

یک مثال کاربری کنسول را دانلود کنید تا کمی در دنیای واقعی بهتر متوجه مطلب شوید . همچنین برای فهم دقیقتر مطلب می توانید از کتاب   

  Illustrated C# 2008 از انتشارات Apress  استفاده کنید

 دانلود

وراثت چند گانه قسمت ۱

در مطالب قبلی در مورد کلاسها برخی مطالب را نوشتم که شاید مفید بوده . تفاوت شی گرایی از دید برنامه نویسی و تحلیل را بررسی کردم .

یکی از ارکان مهم شی گرایی ،  وراثت است . البته قصد ندارم وراثت یگانه را بحث کنم . و دانستن این مبحث را به خواننده واگذار می کنم . بلکه انچه که می خواهم بحث کنم وراثت چند گانه است .

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

اما اگر از دیدی مفهومی و تحلیلی به وراثت نگاه کنیم متوجه می شویم که وراثت چندگانه از مهمترین ارکان اشیا موجود در اطراف ماست .

اکنون این سوال مطرح می شود که با توجه به واقعیت و حقیقت وجودی وراثت چندگانه ، پس چرا زبانهای امروزی مانند سی شارپ و جاوا از وراثت چند گانه بی بهره هستند .

 

لینک مطلب

در لینک بالا نقل قول مستقیم از Chris Brumme کرده. Chris کیه؟ یکی از اعضای تیم CLR مایکروسافت از سال 2003 بوده ، پس هر کسی نیست و همینجوری حرف نمیزنه.

 

بدلیل اینکه مایکروسافت قرار بود در ابتدا .net  را بر اساس چند زبان قرار دهد یعنی vb , c#  و غیره

اگر می خواست وراثت چند گانه را اضافه کند باید این امکان را به .net  اضافه می کرد یعنی خصوصیتی مشترک بین تمام زبانهای دات نت میشد ، این مسله باعث پیچیدگی زبانی مثل vb  می شد که با اهداف مایکروسافت همخوانی ندارد

لذا شرکت مایکروسافت مبنا را بر این قرار داد که از آنجا که اغلب کاربران کمتر به مباحث وراثت چند گانه نیاز دارند پس فعلا برای جلوگیری از پیچیدگیهای زبان ، از این امکان صرفنظر می کند. و فقط راههکار استفاده از  Interface    را بعنوان جایگزینی برای وراثت چند گانه مطرح می کند .

 

وراثت چند گانه با استفاده از interface

 

ما در واقع  با استفاده از interface   وراثت چندگانه را شبیه سازی می کنیم ، چرا که Interface  ها نمی توانند تمام ابعاد وراثت چندگانه را پیاده سازی کنند . بعدها بیشتر در این مورد مطلب می نویسم

اما فعلا وراثت را با استفاده از  Interface  توضیح می دهیم . همانطور که قبلا در مورد  Interface گفتم ، یک کلاس می تواند از بیش از یک Interface ارث بری کند و این شرط کافی برای وراثت چند گانه است .فرض کنید کلاس c  از دو کلاس  A , B   بصورت همزمان مانند شکل زیر ارث بری می کند

یعنی کد نویسی آن بصورت زیر باید باشد :


class A
}
m1();
}
class B
{
m2();
}
class C : A, B
{
m1();
m2();
}

اما در دنیای واقعی کدهای بالا صحیح نیست و امکان پذیر نیست ، چون ما از وراثت چندگانه به شکل بالا نمی تواینم استفاده کنیم پس باید ازیک کلاس مثلا  A  بصورت مستقیم ارث بری کنیم و برای کلاس بعدی یک  Interface  تعریف می کنیم تا از آن ارث بری کنیم یعنی کلاس C  ما باید مستقیما از کلاس A  و از Interface  کلاس  B  ارث بری کند شکل زیر را ببینید :




.

 

وکدهای مثال بالا:

class A
{
m1();
}

interface IB
{
m2();
}

class B : IB
{
m2();
}

class C : A, IB
{
B BObject;
m1();
m2() { BObject.m2();

}

در کد فوق ابتدا آینترفیس  IB  را تعریف می کنیم ، کلاس B  از اینترفیس IB  ارث بری می کند یعنی کلاس B  باید قوانین موجود در اینترفیس IB  را اعمال کند و در اکنون کلاس C  از کلاس A  بصورت معمولی و مستقیم ارث بری می کند اما در مورد کلاس B   ، ابتدا اینترفیس IB  را تعریف کردیم که کلاس c  از آن ارث بری کند سپس در تعریف کلاس C  متغیری از نوع کلاس B   تعریف می کنیم که به هنگام فراخوانی متدهای اینترفیس در حقیقت متدهای کلاس B  را فراخوانی می کنیم .