"> Delegate ها و EventHandler برای Event ها در سی شارپ | ام اس پی سافت

Delegate ها و EventHandler برای Event ها در سی شارپ

Delegate

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

delegate چیست؟

یک delegate مانند اشاره گری به یک تابع است .این مرجع یک روش را در اختیار دارد.

تمامی delegate ها از کلاس System.Delegate استفاده میکنند.

قاعده ی Delegate =>

(<access modifier> delegate <return type> <delegate_name>(<parameters>

برای مثال :

public delegate void SendMessage(string message);  

delegate مربوط به SendMessage  فوق، می تواند جهت اشاره به هر متدی که نوع بازگشتی و پارامترهای تعریف شده مشابه با SendMessage دارد، استفاده شود.

Event چیست؟

Event ها شیء یا کلاسی را جهت اعلان دیگر اشیاء یا کلاس ها هنگامی که رخداد مورد نظری پیش آید، فعال می کنند.

کلاسی که event را ارسال  می کند، publisher  و کلاس هایی که event را دریافت یا مدیریت میکنند، subscribers نامیده میشوند.

یک event دارای یک publisher, subscriber, notification and a handler می باشد.

در عمل،event چیزی جز delegate کپسوله شده نیست.

قاعده ی Eventها =>

<access modifier> event <delegate_name> EventName;
یا
<access modifier> event EventHandler <custom event class> EventName;
یا
<access modifier> event EventHandler EventName;

برای مثال:

public event MessageLoggedEventHandler MessageLogged;  

کاربرد اصلی event ها و delegate ها برقراری اتصال بین اشیاء می باشد. به شما نشان خواهیم داد که این امر چه کمکی می کند.

حال بیایید شروع کنیم.

یک  LoggerService ایجاد خواهیم کرد که Log ها را خواهد نوشت و هنگامی که Log ها نوشته شد، Mail/Message را بر اساس event های مورد اشتراک ارسال خواهد کرد.

ابتدا بیایید یک کلاسPublisher) Logger ) ایجاد کنیم که وظیفه ی انتشار Event را بر عهده خواهد داشت.

/// 
<summary>  
   ///  Create a Publisher by -  
   ///  ۱ - Define delegate  
   ///  ۲ - Define an Event based on delegate  
   ///  ۳ - Raise the event  
   /// </summary>

  
   ///   
   public class Logger  
   {  
       public delegate void DataLoggedEventHandler(object source, EventArgs args);  
       public event DataLoggedEventHandler MessageLogged;  
       public void WriteLog(string message)  
       {  
           Console.WriteLine($"Message: {message}");  
           Thread.Sleep(4000);  
           OnMessageLogged();// raise event  
       }  
       // .Net recommends - Event method should be protected, virtual, void and start with On<Eventname>  
       protected virtual void OnMessageLogged()  
       {  
           if (MessageLogged != null)  
               MessageLogged(this, EventArgs.Empty);  
       }  
   }  

در کد فوق، یک  DataLoggedEventHandler) delegate) جهت نگهداری مرجع متد دارای امضای مشابه ایجاد کردیم.

سپس، رویدادی برای DataLoggedEventHandler ایجاد کردیم که به Subscriber امکان اشتراک را خواهد داد.

در آخر، یک متد رویداد OnMessageLogged() که مسئول فراخوانی متدهای مورد اشتراک به ترتیب می باشد، ایجاد کردیم.

اکنون، یک کلاس Subscriber)  MailService) ایجاد خواهیم کرد که وظیفه ی ارسال پیام هنگامی که event اتفاق می افتد را بر عهده خواهد داشت.

public class MailService  
    {  
        public void OnMessageLogged(object source,EventArgs args)  
        {  
            Console.WriteLine("Sending Mail...");  
            Thread.Sleep(3000);  
            Console.WriteLine("Mail Sent");  
        }  
    }  

توجه کنید که در اینجا، امضای متد با امضای delegate یکسان است.

حال بیایید یک کلاس Main() که مشترک event ها شده و متد WriteLog() را فراخوانی خواهد کرد، ایجاد کنیم.

public class LoggerService  
    {  
        static void Main()  
        {  
            var logger = new Logger(); // publisher  
            var mailer = new MailService();// subscriber  
 
            #region Subscribe Events  
            logger.MessageLogged += mailer.OnMessageLogged;  
            #endregion  
  
            // Will raise the events  
            logger.WriteLog("This is an error log");  
  
            Console.WriteLine("Event Completed");  
            Console.Read();  
        }  
    } 

اکنون بیایید ببینیم که چگونه اتصال loosely برقرار شده است.

بگذارید فرض کنیم که نیاز است سرویس جدیدی به نام MessageService ایجاد کنیم و همچنین می خواهیم مشترک event شده و action مربوط به OnMessageLogged() که باید برای MessageService انجام شود را فراخوانی کنم.

public class MessageService  
   {  
       public void OnMessageLogged(object source, EventArgs args)  
       {  
           Console.WriteLine("Sending Message...");  
           Thread.Sleep(3000);  
           Console.WriteLine("Message Sent");  
       }  
   }  

حال اگر نیاز باشد آن را مشابه با MailService متصل کنیم، آنگاه تنها باید در کلاس (Calling(Main تغییراتی را اعمال کنیم.

public class LoggerService  
    {  
        static void Main()  
        {  
            var logger = new Logger(); // publisher  
            var mailer = new MailService();// subscriber  
            var messenger = new MessageService();// subscriber  
 
            #region Subscribe Events  
            logger.MessageLogged += mailer.OnMessageLogged;  
            logger.MessageLogged += messenger.OnMessageLogged;  
            #endregion  
  
            // Will raise the events  
            logger.WriteLog("This is an error log");  
  
            Console.WriteLine("Event Completed");  
            Console.Read();  
        }  
    }  

برنامه را اجرا کرده و خروجی را مشاهده کنید.

اکنون مفاهیم Event ها و Delegate و نحوه ی کار آن ها با یکدیگر برای ما آشکار شده است.

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

ما یک CustomEvent فرضا LoggerEvent از طریق ارث بری از EventArgs ایجاد خواهیم کرد.

public class LoggerEvents : EventArgs  
    {  
        public string Message { get; set; }  
    } 

اکنون از event برای ارسال پیام استفاده خواهیم کرد. بیایید تغییرات لازم در کلاس Logger را مشاهده کنیم.

public class Logger  
   {  
       public delegate void DataLoggedEventHandler(object source, EventArgs args);  
       public delegate void DataLoggedEventHandler(object source, LoggerEvents args);  
       public event DataLoggedEventHandler MessageLogged;  
       {  
           Console.WriteLine($"Message: {message}");  
           Thread.Sleep(4000);  
           OnMessageLogged();// raise event  
           OnMessageLogged(message);// raise event  
       }  
       // .Net recommends - Event method should be protected, virtual, void and start with On<Eventname>  
       protected virtual void OnMessageLogged()  
       protected virtual void OnMessageLogged(string message)  
       {  
           if (MessageLogged != null)  
               MessageLogged(this, EventArgs.Empty);  
               MessageLogged(this, new LoggerEvents() { Message = message });  
       }  
   }  

حال با این تغییرات، نیاز است کلاس های Subscriber را نیز جهت انطباق با event دلخواه بروزرسانی کنیم.

public class MailService  
    {  
        public void OnMessageLogged(object source,EventArgs args)  
        public void OnMessageLogged(object source, LoggerEvents args)  
        {  
            Console.WriteLine("Sending Mail...");  
            Thread.Sleep(3000);  
            Console.WriteLine("Mail Sent");  
            Console.WriteLine($"Mail Sent with message - {args.Message}");  
        }  
    }  
public class MessageService  
   {  
       public void OnMessageLogged(object source, EventArgs args)  
       public void OnMessageLogged(object source, LoggerEvents args)  
       {  
           Console.WriteLine("Sending Message...");  
           Thread.Sleep(3000);  
           Console.WriteLine("Message Sent");  
           Console.WriteLine($"Message Sent with message - {args.Message}");  
       }  
   }  

اکنون تنها برنامه را اجرا کرده و مشاهده می کنید که خروجی یکسان خواهد بود.

در آخر، یک مورد ارتقای دیگر کلاس Publisher) Logger ) جهت استفاده از EventHandler به جای delegate. .Net از نسخه ی .Net Framework 2.0 همراه با EventHandler عرضه شد، بنابراین می توانیم از آن به جای delegate ها استفاده کنیم.

بیایید ببینیم چگونه می توانیم تغییراتی را ایجاد کرده و خروجی یکسانی را با کد کاهش یافته بدست آوریم.

 
public class Logger  
    {  
        //public delegate void DataLoggedEventHandler(object source, LoggerEvents args);       
  
        //public event DataLoggedEventHandler MessageLogged;  
  
        public event EventHandler&lt;LoggerEvents&gt; MessageLogged;// if we want to pass any message and used custom EventHandler  
        //public event EventHandler MessageLogged;// if we do not want to pass any message hence not using custom EventHandler  
  
        public void WriteLog(string message)  
        {  
            Console.WriteLine($"Message: {message}");  
            Thread.Sleep(4000);  
            OnMessageLogged(message);// raise event  
        }  
  
        // .Net recommends - Event method should be protected, virtual, void and start with On&lt;Eventname&gt;  
        protected virtual void OnMessageLogged(string message)  
        {  
            if (MessageLogged != null)  
                MessageLogged(this, new LoggerEvents() { Message = message });  
        }  
    } 

با تغییرات فوق، ایجاد delegate را حذف کرده و به جای آن از EventHandler استفاده کرده ایم.

با اجرای برنامه، باید خروجی یکسانی را دریافت کنید.

کار تمام است. در اینجا، مفاهیم eventها، delegate ها و EventHandler ها را در سی شارپ پوشش دادیم.

  • پسورد: www.mspsoft.com
زهره سلطانیان

نوشته‌های مرتبط

دیدگاه‌ها

*
*

این سایت از اکیسمت برای کاهش هرزنامه استفاده می کند. بیاموزید که چگونه اطلاعات دیدگاه های شما پردازش می‌شوند.

کدیشن ! مارکت پروژه های برنامه نویسی راه اندازی شدیه توکه پا بریم ببینم