برق. قدرت. کنترل. الکترونیک. مخابرات. تاسیسات.

دایره المعارف تاسیسات برق (اطلاعات عمومی برق)

در مثال قبلی با پیاده سازی کلاس EmpCustomer به مقصود خود رسیدیم و در واقع می توانستیم که اشیایی از این نوع را هم به ICustomer و هم به IEmployee نسبت دهیم. حالا به کد زیر دقت کنید:




همانطور که می بینید من 3 شیء جدید ایجاد کرده ام. 2 تا Employee و یک EmpCustomer و آنها را به عنوان کارمند در لیست کارمندان شرکت اضافه نموده ام. و همینطور 2 شیء دیگر که از نوع Customer هستند. و به همراه شیء قبلی که از جنس EmpCustomer بود به لیست مشتریان شرکت اضافه کرده ام. حالا اگر از شیء شرکت متد های چاپ لیست مشتریان و چاپ لیست کارمندان را فراخوانی کنم نتیجه زیر را خواهیم دید.



این نتیجه در واقع نتیجه درستی است چرا که من 3 مشتری و 3 کارمند دارم. اما نکته ای که وجود دارد این است که شیء EmpCustomer من در موقع نمایش اطلاعات خود ، با ما بقی اشیاء من متفاوت است. یعنی وقتی در لیست کارمندان نمایش داده می شود تفاوت آن با بقیه کارمند و در لیست مشتریان با بقیه مشتریان مشهود است. اما من می خواهم که در هر دو حالت کاملا شبیه به این دو نوع باشد و رفتاری مشابه بقیه داشته باشد. در نتیجه من باید از Explicit Interface Implementation استفاده کنم.

Explicit Interface Implementation
این روش موقعی استفاده می شود که شما می خواهید رفتار یک شیء را بسته به نوع reference آن تعیین کنید. یعنی وقتی به یک شیء از جنس EmpCustomer از دیدگاه ICustomer نگاه می کنید رفتاری شبیه مابقی ICustomer ها داشته باشد و وقتی از دید IEmployee نگاه می کنید رفتاری شبیه به مابقی IEmployee ها داشته باشد و در حالتی که از دید EmpCustomer نگاه می کنید رفتار خاص دیگر داشت باشد. در مثال ما شما باید متد Print را سه مرتبه پیاده سازی کنید. به این کد دقت کنید:



همانطور که می بینید در پیاده سازی های دوم و سوم ابتدا نام interface و سپس دقیقا اسم متد را به همان ترتیب که در interface ها نوشته شده است و بدون access modifier می نویسیم. در پیاده سازی متد نیز کاملا شبیه به Employee و Customer عمل خواهیم کرد. در نتیجه اگر مثال قبلی را دوباره اجرا کنید خروجی به شکل زیر خواهید داشت.



بارگزاری مثال
Delegates in CSharp
بعد از بررسی اینترفیس ها باید به بررسی دلیگیت ها بپردازیم. برای این بررسی ابتدا من یک تعریف از Delegate خواهم گفت. سپس به روش ایجاد (Syntax) دلیگیت ها می بپردازم و در نهایت به دلایل استفاده یا مثال های آن خواهم پرداخت. لطفا سعی کنید که در بررسی delegate ها کمی حوصله کنید و با دقت مطالب را مطالعه کنید.

delegate چیست؟
delegate ها type هایی هستند که اشیاء آن ها می توانند متد های کلاس های دیگر و متد های اشیاء دیگر را فرخوانی کنند. در واقع یک شیء از یک دلیگیت برای فراخوانی متد های کلاس ها و اشیاء دیگر ایجاد می شود.

چگونه یک delegate تعریف کنیم؟
من برای ایجاد یک delegate چهار مرحله در نظر می گیرم.
  1. تعریف delegate یا Delegate Definition
  2. ایجاد reference از delegate یا Delegate Declaration
  3. ایجاد شیء یا Delegate Initialization
  4. فرخوانی یا Calling
اجازه بدین این مراحل را با یک مثال ساده بررسی کنیم.
مرحله اول باید در namespace نوشته شود. همانند یک کلاس یا type های دیگر. وقتی می خواهیم یک delegate را بنویسیم باید بدانیم که این delegate برای فراخوانی چه متدهایی نوشته شده است.

همان طور که در تصویر می بینید من یک delegate را در فضای namespace تعریف کرده ام. با توجه به کد نوشته شده ، این delegate امکان فرخوانی متد هایی را که خروجی ندارند (void) و همینطور هیچ پارامتری هم ندارند ، دارد. استفاده از کلمه CallBack در انتهای نام delegate ها پیشنهاد می شود.

حالا باید یک reference از آن delegate ایجاد کنیم:


در مرحله سوم باید این reference را new کنیم:



در این مرحله باید شما نام یک متد و فقط نامش را به عنوان پارامتر به constructor این delegate پاس دهید. توجه کنید که تمامی delegate ها دارای Constructorی با یک پارامتر می باشند که اسم یک متد خواهد بود. متدی که پاس می شود باید دقیقا ساختاری شبیه به ساختار تعریف شده delegate شما (مرحله 1) داشته باشد.

مرحله آخر فراخوانی delegate است:



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

نکته مهم این است که شما می توانید بیش از یک متد (با ساختار شبیه به هم) را داخل یک delegate قرار دهید. برای این کار به جای استفاده از = موقع new کردن از =+ استفاده خواهیم کرد. وقتی این delegate را فراخوانی می کنید تمامی آن ها به ترتیب فراخوانی خواهند شد.

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

اجازه بدین با یک مثال ادامه بدیم:

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

خوب پس من یک کلاس خواهم داشت به نام Customer و یک کلاس هم به نام Agent:



همانطور که می بینید کلاس Customer دارای یک متد به نام Buy است که از این طریق خرید انجام می شود. نکته مهم این است که باید کدی بنویسیم که وقتی یک مشتری خرید می کند تمام بازرسان متوجه خرید بیش از اعتبار وی شوند.



در کلاس Agent یک ArrayList برای ثبت فعالیت های هر یک از بازرسان در نظر گرفته شده است که برای ثبت پیگیری جدید باید از متد AddTask استفاده شود. پس ما باید به طریقی AddTask تمامی بازرسان را همزمان و در متد Buy کلاس Customer فراخوانی کنیم.

برای انجام این موضوع من یک Delegate متناسب با متد AddTask ایجاد می کنم (مرحله اول).



حالا در کلاس Agent یک متغییر static (برای همه بازرسان) از جنس آن delegate ایجاد می کنم. (مرحله دوم)
سپس در Constructor کلاس Agent متد AddTask هر یک از بازرسان را در delegate ثبت می کنم. (مرحله سوم).

در نهایت موقعی که اعتبار مشتری من منفی می شود delegate static را فراخوانی می کنم. در نتیجه به تمامی بازرسان یک وظیفه جدید اضافه خواهد شد.


و حالا کافیست چند شیء از هر کدام از کلاس ها بسازم و شروع به تست کنم:



و در نتیجه:




این مثال را مرور کنید. مسلما برای دوستانی که تازه با سی شارپ آشنا شده اند خیلی سنگین خواهد بود. اصلا مهم نیست کافیه که توی ذهنتون چند باری مرورش کنید. به نظر من delegate سنگین ترین بحث سی شارپ است. پس اصلا به خودتون شک نکنید!

بارگزاری مثال

رویداد ها در سی شارپ - Events in CSharp
اغلب نرم افزار هایی که تولید می شوند ساختاری Event Driven1 دارند. به عنوان مثال شما یک فرم ایجاد می کنید و کاربر با پر کردن اطلاعات فرم و در نهایت کلیک بر روی گزینه ذخیره فرم اطلاعاتی مورد نظر را ذخیره می نماید.
پر کردن فرم ، کلیک بر روی گزینه Save و ... همگی رویداد هایی هستند که از طرف کاربر شما ارجاع می شود و چک کردن اطلاعات و ذخیره کردن اطلاعات و ... هم پاسخ (عکس العمل) های شما به آن رویداد ها.

برای تولید و استفاده یک رویداد در سی شارپ 7 مرحله پیاده سازی وجود دارد. 5 مرحله اول برای تولید رویداد (Event Raise) و 2 مرحله آخر برای پاسخ به رویداد (Event Handler) می باشد.

در بررسی رویداد ها با یک مثال ساده شروع می کنیم. یک انبار را در نظر بگیرید. در این انبار وقتی تعداد یک کالا به صفر می رسد یک رویداد باید اعلام شود و در نتیجه آن رویداد مسئول انبار درخواست خرید چند آیتم از آن کالا را صادر خواهد کرد. کلاس انبار را به صورت زیر تعریف میکنم. برای ثبت محصول از متد AddProduct و برای دریافت کالا از متد GetProduct استفاده می شود. در صورتیکه تعداد کالا به صفر برسد ، رویداد مورد نظر باید اعلام شود.

برای تعریف رویداد ، ابتدا یک delegate تعریف می کنیم (مرحله اول):



دقت کنید که delegate هایی که به منظور تولید Event ها ایجاد می شوند همواره دارای دو پارامتر می باشند. پارامتر اول از نوع object که در واقع شیء است که رویداد بر روی آن اتفاق می افتد. پارامتر دوم از نوع EventArgs یا کلاس های که از آن به ارث رفته باشد. پارامتر دوم در واقع اطلاعات یا آرگومان های رویداد می باشد. 2
در مرحله دوم یک event در کلاس Warehouse تعریف می کنیم (مرحل دوم):



در مرحله بعدی یک متد protected به نام OnLowAmount تعریف می کنیم (مرحله چهارم3)



و سپس در زمان مناسب (موقعی که تعداد کالا به صفر برسد) رویداد را با استفاده از متد protected مرحله قبل اعلام می کنیم (مرحله پنجم):




سپس شروع به استفاده از این کلاس خواهم کرد:



همانطور که می بینید در این کلاس رویداد LowAmount به صورت یک Event (با شکلی شبیه علامت برق) مشخص شده است.

مرحله بعدی ایجاد یک متد است که با ساختار delegate رویداد مورد نظر مطابقت داشته باشد (مرحله ششم):



و در نهایـت وصل کردن این متد (مرحله ششم) به رویداد با استفاده از =+ می باشد. (مرحله هفتم):



دقت فرمائید که در صورتیکه تمایل داشته باشید می توانید بیش از یک متد را داخل رویداد خود به عنوان EventHandler قرار دهید:

2. به عنوان مثال در رویداد KeyDown بر روی کلاس Form از کلاس KeyٍEventArgs استفاده شده است.

3. در این مثال نیازی به وجود مرحله سوم نمی باشد.

دانلود مثال این قسمت

رویداد ها و آرگیومنت های خاص - Event and Custom EventArgs

بسیاری از رویداد ها در هنگام وقوع دارای جزئیاتی می باشند. به عنوان مثال رویداد MouseMouse دارای اطلاعات همچون محل Cursor موس می باشد یا در رویداد KeyDown کلیدی که تایپ شده است از اطلاعات خاص این رویداد است. ایجاد رویداد ها و پاس کردن اطلاعات خاص آن رویداد ها توسط کلاس هایی که از کلاس پایه ای به نام EventArgs به ارث رفته اند ، اعلام می گردد.

برای بررسی این موضوع از یک مثال استفاده می کنیم. فرض کنید که در مثال قبلی می خواهید که در موقع بروز رویداد LowAmount امکان جلوگیری از خریدی در حال وقوع را داشته باشیم. پس شما باید یک متغییر boolean در پارامتر های رویدادتان به نام Cancel تعریف کنید که در صورتی که توسط متد EventHandler به True ست شده باشد باید از خرید جلوگیری نمائید.

برای اجراء این موضوع یک کلاس به نام LowAmountEventArgs تعریف می کنیم (این کلاس از کلاس EventArgs به ارث می رود) و در آن یک متغییر به نام Cancel از جنس bool تعریف می کنم:



سپس delegate مربوط به رویداد را به صورت زیر تغییر می دهم:



همچنین در زمان رویداد یک شیء از جنس LowAmountEventArgs ایجاد می کنم:



حالا در زمان رویداد این امکان وجود دارد که کاربر از ثبت این برداشت از انبار جلوگیری کند. برای این کار کافیست که کاربر شما در event handler مربوط به استفاده از متغییر موجود مقدار Cancel را به True ست کند.



نمونه های بسیاری از این نوع رفتار ها در دات نت وجود دارد ، به عنوان مثال در کلاس Form در Windows Application وقتی درخواست بسته شدن فرم از طرف کاربر ارسال می شود ، یک رویداد به نام FormClosing رخ می دهد ، در صورتیکه شما یک EventHandler برای این رویداد بنویسید می توانید با ست کردن متغییر Cancel در کلاس FormClosingEventArgs می توانید مانع از بسته شدن فرم شوید.

دانلود مثال این پست


صفحات جانبی

نظرسنجی

    لطفاً نظرات خود را درمورد وبلاگ با اینجانب در میان بگذارید.(iman.sariri@yahoo.com)نتایج تاکنون15000مفید و 125غیرمفید. با سپاس


  • آخرین پستها

آمار وبلاگ

  • کل بازدید :
  • تعداد نویسندگان :
  • تعداد کل پست ها :
  • آخرین بازدید :
  • آخرین بروز رسانی :