<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      delegate、event、EventHandler、Action、Func的使用和區別

      delegate、event、EventHandler、Action、Func的使用和區別

      【目錄】

      1 委托

      2 事件-概念的引出

      3 事件-關于異常

      4 事件-關于異步

      5 委托-Func與Action

       

      1 委托

      在.NET中定義“委托”需要用到delegate關鍵字,它是存有對某個方法的引用的一種引用類型變量,類似于 C 或 C++ 中函數的指針?!拔小敝饕袃纱笞饔茫海?)將方法當作參數傳遞
      (2)方法的一種多態(類似于一個方法模板,可以匹配很多個方法)下面,給出一個展現了上述兩大作用的委托代碼示例:
              //定義一個委托        public delegate int MyDelegate(int x, int y);
      //與委托匹配的一個方法 public static int Add(int a, int b) { return a + b; }
      //與委托匹配的另一個方法 public static int Reduce(int a, int b) { return a - b; }
      //示例:將委托/方法當參數傳遞 public static int Test(MyDelegate MD) { return MD(10, 20); }
      static void Main(string[] args) { int a, b, x, y;
      MyDelegate md;
      //將委托指向Add這個方法,并進行相關操作 md = Add; a = md(1, 2); b = Test(md);
      //再將委托指向Reduce這個方法,并進行相關操作 md = Reduce; x = md(7, 2); y = Test(md);
      Console.WriteLine($"1+2={a},10+20=,7-2={x},10-20={y}"); Console.ReadLine(); }
      執行以上程序,輸出結果如下:1+2=3,10+20=30,7-2=5,10-20=-10

       

       
      委托也可以使用+=/-=來實現“發布/訂閱”模式,示例代碼如下:
              //定義一個委托        public delegate void MyDelegate1(int x);
      public static void Method1(int a) { Console.WriteLine($"a={a}"); }
      public static void Method2(int b) { Console.WriteLine($"b="); }
      static void Main(string[] args) { MyDelegate1 md = null; md += Method1; md += Method2; md(35);
      Console.ReadLine(); }
      以上程序輸出如下:a=35

      b=35

      但是委托有一個弊端,它可以使用“=”將所有已經訂閱的取消,只保留=后的這一個訂閱。

      為了解決這個弊端,事件event應運而生。

      2 事件-概念的引出

      事件event是一種特殊的委托,它只能+=,-=,不能直接用=。event在定義類中(發布者)是可以直接=的,但是在其他類中(訂閱者)就只能+= -=了,也就是說發布者發布一個事件后,訂閱者針對他只能進行自身的訂閱和取消。下面是定義一個事件的代碼:
              //定義一個委托        public delegate void MyDelegate1(int x);        //定義一個事件        public event MyDelegate1 emd;

      經過長久的經驗積累后,人們發現,絕大多數事件的定義,是用public delegate void XXX(object sender, EventArgs e);這樣一個委托原型進行定義的,是一件重復性的工作,于是,EventHandler應運而生。它的出現就是為了避免這種重復性工作,并建議盡量使用該類型作為事件的原型。
      //@sender: 引發事件的對象//@e: 傳遞的參數public delegate void EventHandler(object sender, EventArgs e);
      //使用public event EventHandler emd;

      下面給出一個使用事件的具體示例:
              public class Demo        {            public event EventHandler emd;            public void RaiseEvent()            {                emd(this, EventArgs.Empty);            }        }
      static void Main(string[] args) { var instance = new Demo(); instance.emd += (sender, arg) => { Console.WriteLine("執行事件1!"); };
      instance.emd += (sender, arg) => { Console.WriteLine("執行事件2!"); };
      instance.RaiseEvent();
      Console.ReadLine(); }
      這里我們先定義一個Demo類,其內部有個事件是emd,我們給他開放了一個接口RaiseEvent,如果誰敢調用它,那么,它就觸發報警事件emd。
      這里模擬了2個訂閱者,分別處理報警事件emd。程序執行結果如下:執行事件1!執行事件2!同時,我們也可以看出:事件是按照+=的訂閱先后順序執行的。

      3 事件-關于異常

      現在,我們在第一個訂閱者中加入異常,如下:

          instance.emd += (sender, arg) =>    {        Console.WriteLine("執行事件1!");        throw new Exception("執行事件1,錯誤");    };
      執行后發現,第1個訂閱者事件觸發拋出異常后,第2個訂閱者的事件沒有執行。

      可見,如果你想讓所有訂閱者都執行處理的話,那每個訂閱者必須在訂閱程序內自己處理好異常,不能拋出來!

       

      4 事件-關于異步

      如果事件的訂閱者中有一個是“異步”處理,又會是什么情況?下面我們把第1個訂閱者改為異步處理,代碼如下:
          instance.emd += async (sender, arg) =>    {        Console.WriteLine("執行事件1!");        await Task.Delay(1000);        Console.WriteLine("執行事件1!完畢");    };
      執行后輸出如下:
      執行事件1!執行事件2!

      執行事件1!完畢

      可見,異步的事件處理沒有阻塞進程,很好的起到了異步方法的作用。

      5 委托-Func與Action

      本文最開始探討委托,然后直接順到了事件的相關話題上。其實,關于委托還有一個重點話題漏掉了,那就是Func與Action。

      在委托delegate出現了很久以后,微軟的.NET設計者們終于領悟到,其實所有的委托定義都可以歸納并簡化成只用Func與Action這兩個語法糖來表示。其中,Func代表有返回值的委托,Action代表無返回值的委托。有了它們兩,我們以后就不再需要用關鍵字delegate來定義委托了。

      同時,若再用lambda表達式取代被委托指向的具體方法,則整個委托的“定義+賦值”兩步將大大簡化(lambda表達式本來也是方法定義的一種簡化形式)。

      下面,把最開始委托章節中關于加減法的程序代碼,用Func與lambda表達式進行簡化改造,改造后的代碼如下:

              //示例:將委托/方法當參數傳遞        public static int Test(Func<int, int, int> MD)        {            return MD(10, 20);        }
      static void Main(string[] args) { int a, b, x, y;
      Func<int, int, int> md;
      //將委托指向加法,并進行相關操作 md = (t, v) => t + v; a = md(1, 2); b = Test(md);
      //再將委托指向減法,并進行相關操作 md = (t, v) => t - v; x = md(7, 2); y = Test(md);
      Console.WriteLine($"1+2={a},10+20=,7-2={x},10-20={y}"); Console.ReadLine(); }

       

      posted @ 2023-04-07 13:21  春光牛牛  閱讀(271)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 毛片免费观看天天干天天爽| 性色欲情网站iwww九文堂| 亚洲人成网网址在线看| 熟女少妇精品一区二区| 国产伦精品一区二区三区妓女| 国产午夜精品福利视频| 国产美女69视频免费观看| 国产精品夜夜春夜夜爽久久小说| 一区二区亚洲精品国产精| 欧美成本人视频免费播放| 久久精品国产亚洲av麻豆长发| 亚洲人成网站77777在线观看| 欧美老熟妇乱子伦牲交视频| 强奷漂亮少妇高潮伦理| 久久av无码精品人妻出轨| 欧美国产日韩在线三区| 亚洲夂夂婷婷色拍ww47| 亚洲一区二区三区av链接| 欧美人与zoxxxx另类| 中日韩中文字幕一区二区| 无码人妻精品一区二区三区夜夜嗨| 日本黄页网站免费观看| 无码中文字幕av免费放| 中日韩黄色基地一二三区| 国产普通话对白刺激| 亚洲综合网一区中文字幕| 天天做天天爱夜夜爽导航| 国产精品麻豆成人AV电影艾秋| 欧美黑人巨大xxxxx| 宅男噜噜噜66在线观看| 久久综合开心激情五月天| 国产午夜福利视频合集| 北辰区| av高清无码 在线播放| 噜噜噜噜私人影院| 安平县| 国产乱码精品一区二区上| 欧洲成人在线观看| 亚洲精品一区二区三区大桥未久 | 免费一本色道久久一区| 性奴sm虐辱暴力视频网站 |