c#中的delegate(委托)和event(事件)


委托: 托付其他人做這件事   ,包括 托付自己  ,即  一個方法 可以  調用 沒有關系的其他方法 , 也可以 將委托傳遞過去 ,回調自己的方法 ,且 可以自定義參數 ,非常方便 互相傳值, 適合解耦 關系。

 示例:

       public delegate void ChangeMoney(object s, int n);   // 用 delegate  聲明委托

 

   1、 調用 其他方法

           售賣 頁面添加商品,添加 的 商品 在另一個頁面也能看見 。

                 售賣頁面 類里面 定義委托:

                    //定義一個委托
                        public delegate void GetProductHander(List<MarkingModel> mlist);
                  // 將創建的委托和特定事件關聯
                  public static event GetProductHander getproduct;

           //點擊添加商品時  調用 委托方法:                

                   if(點擊添加商品)

                      {     

                          getproduct.Invoke(_list);         

                   }     

             另一個頁面調用委托:

                          ProductSaleMarketing.getproduct += new ProductSaleMarketing.GetProductHander(GetList);

                           // 將 要調用的 GetList 方法 放到  getproduct  (從類里面點出來)后面。 以及實現 GetList 方法

                         private void GetList(List<MarkingModel> _mlist)
                        {

                        }

      2.  相當於回調方法

                  這個要在類外面定義委托 ,因為 回調  是 在其他頁面實例化委托 ,調用 連接的方法。  誰在后邊 后邊調用誰。

         

public delegate void ChangeMoney(object s, int n);  // 在頁面外邊  聲明委托   其他頁面都可調用

public partial class TiHuoBill : BaseForm
{

                          //多窗口共用事件
                            private void sn_EveDelSelectNumber(object cash, int n)
                                {
                                    ChangePay(cash, n);
                                 }


                       //現金
                          private void btnCash_Click(object sender, EventArgs e)
                      {
                             var sn = new ShowNumber(7);
                                   sn.CardMoney = _daishou;
                                   sn.EveDelSelectNumber += sn_EveDelSelectNumber;  //  主要就是 這句話  委托在ShowNumber 頁面 實例化了, +=   即  那個頁面執行后  調用 sn_EveDelSelectNumber
                                   sn.ShowDialog();
                     }

}

   ShowNumber 頁面 :

          public ChangeMoney EveDelSelectNumber;   //  實例化委托

                   // 確定關閉頁面的時候 

                   private void btnSure_Click(object sender, EventArgs e)
                     {

                                 EveDelSelectNumber(SelectMoney, SelectType);  // 調用委托 並傳值   或者這種方式:   EveDelSelectNumber.Invoke(SelectMoney, SelectType);

                      }

 

         暫時發現 委托 可以使用這兩種方式

        其中  delegate  和 event  效果 是一樣的  

     區別  :event與delegate的區別
 首先,通過加入event關鍵字,在編譯的時候編譯器會自動針對事件生成一個私有的字段(與此事件相關的委托),以及兩個訪問器方法,即add訪問器方法以及remove訪問器方法,用於對事件的注冊及注銷(對事件使用+=及-=操作時就是調用的這兩個方法)。
我想你們的問題主要是,實際上聲明一個委托類型的字段也可以實現這些功能。
實際上之所以采用event而不直接采用委托,實際上還是為了封裝。可以設想一下,如果直接采用公共的委托字段,類型外部就可以對此字段進行直接的操作了,比如將其直接賦值為null。
而使用event關鍵字就可以保證對事件的操作僅限於add訪問器方法以及remove訪問器方法(即只能使用+=及-=)

  

    在Msdn中,有一段話描述Delegate和Event之間的關系,其實很簡單:

        聲明事件:若要在類內聲明事件,首先必須聲明該事件的委托類型。

 

    委托還適用於 觀察者模式:

                 

    class Program
    {
        static void Main(string[] args) { var car = new Car(15); new Alerter(car); car.Run(120); } } class Car { public delegate void Notify(int value); public event Notify notifier; private int petrol = 0; public int Petrol { get { return petrol; } set { petrol = value; if (petrol < 10) //當petrol的值小於10時,出發警報 { if (notifier != null) { notifier.Invoke(Petrol); } } } } public Car(int petrol) { Petrol = petrol; } public void Run(int speed) { int distance = 0; while (Petrol > 0) { Thread.Sleep(500); Petrol--; distance += speed; Console.WriteLine("Car is running... Distance is " + distance.ToString()); } } } class Alerter { public Alerter(Car car) { car.notifier += new Car.Notify(NotEnoughPetrol); } public void NotEnoughPetrol(int value) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("You only have " + value.ToString() + " gallon petrol left!"); Console.ResetColor(); } }

看完了上面的代碼后,你可能會問:為什么不在public int Petrol中直接調用Alerter.NotEnoughPetrol呢?因為Car模塊和Alerter模塊本身是兩個獨立的子系統,如果直接調用,耦合性就會增加,這不是我們願意看到的。

    其實以上的代碼是設計模式中的觀察者模式(觀察者模式又稱Source/Listener模式)的實現,當汽車在運行中汽油量<10時,警報器便會發出警報。在上面代碼中,Delegate相當於一個存放回調函數的函數指針,使用Delegate,我們可以非常方便地實現觀察者模式。而其實,在需要使用回調函數時,我們都可以考慮使用Delegate。

    不知道你有沒有發現在上面的代碼中還有一個問題呢?

public event Notify notifier;

上面的代碼中,我們定義了一個Event,而事實上:

public Notify notifier;

 

這樣寫,也完全可以滿足我們的需求,這就引出了我們的另一個問題,Delegate和Event!  如上 有說明。

 

               參考:   談C#中的Delegate

                             event與delegate的區別

                            終於會用c#中的delegate(委托)和event(事件)了

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM