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

委託: 託付其餘人作這件事   ,包括 託付本身  ,即  一個方法 能夠  調用 沒有關係的其餘方法 , 也能夠 將委託傳遞過去 ,回調本身的方法 ,且 能夠自定義參數 ,很是方便 互相傳值, 適合解耦 關係。html

 示例:c#

       public delegate void ChangeMoney(object s, int n);   // 用 delegate  聲明委託設計模式

 

   一、 調用 其餘方法函數

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

                 售賣頁面 類裏面 定義委託:url

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

           //點擊添加商品時  調用 委託方法:                .net

                   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(事件)了

相關文章
相關標籤/搜索