中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C#之委托與事件

發布時間:2020-07-17 10:17:07 來源:網絡 閱讀:760 作者:jinyuan0829 欄目:編程語言

委托與事件

 

廢話一堆:網上關于委托、事件的文章有很多,一千個哈姆雷特就有一千個莎士比亞,以下內容均是本人個人見解。

1. 委托

1.1 委托的使用

        這一小章來學習一下怎么簡單的使用委托,了解一些基本的知識。

        這里先看一下其他所要用到的類的信息

         /// <summary>

         /// 函數用例

         /// </summary>

        public class ManyMethodClass

        {

             public ManyMethodClass() { }

             /// <summary> 

             /// 實例函數

             /// </summary>

             /// <param name="strmes"></param>

             public void InstanceMethod(string strmes)

             {

                   Console.WriteLine("實例函數輸出:" + strmes);

             }

            /// <summary>

            /// 靜態函數

            /// </summary>

            /// <param name="strmes"></param>

            public static void StaticMethod(string strmes)

            {

               Console.WriteLine("靜態函數輸出:" + strmes);

            }

        }

  • 定義一個委托類型

            public delegate void DisplayStringDelegate(string strmes); 

  • 實例化委托類型

            //綁定實例函數 第一種定義方式(實例函數)

            DisplayStringDelegate disstrdele_instance = new DisplayStringDelegate(newManyMethodClass().InstanceMethod);

            //綁定靜態函數 第二種定義方式(靜態函數)

            DisplayStringDelegate disstrdele_static = new DisplayStringDelegate(ManyMethodClass.StaticMethod);

            //綁定委托實例 第三種定義方式(委托實例)

            DisplayStringDelegate disstrdele_delegate = new DisplayStringDelegate(disstrdele_instance);

  • 調用委托實例

            disstrdele_instance.Invoke("Hello Word");

            disstrdele_static("Hello Word");

            disstrdele_delegate("Hello Word");

          (ps:這里不同的調用方式效果都是一樣的,在下一節會有講到)

        最后讓我們看一下最終的效果圖:

C#之委托與事件

1.2 委托的定義

  • 委托類型類型

            /// <summary>

            /// 委托示例類

            /// </summary>

           public class DelegateDemonStration

           {

                 public DelegateDemonStration() { }

                 public delegate void DisplayStringDelegate(string strmes);

           }

           在上面的示例代碼中,我們定義了一個委托示例類DelegateDemonStration,在DelegateDemonStration的內部我們定義了上一節中講到的委托的類型DisplayStringDelegate

           在這里先不談DisplayStringDelegate它定義簽名類型,先來談談它到底是什么樣的存在。

我們來看一下代碼:

            /// <summary>

            /// 委托示例類

            /// </summary>

            public class DelegateDemonStration

           {

                   public DelegateDemonStration() { }

                   public class DisplayStringDelegate : MulticastDelegate

                   {

                          public DisplayStringDelegate(object @object, IntPtr method){}

                          public virtual  IAsyncResult BeginInvoke(string strmes, AsyncCallback callback, object @object);

                          public virtual void EndInvoke(IAsyncResult result);

                          public virtual void Invoke(string strmes);

                    }

           }

           當我們定義好一個委托類型的時候,在運行時C#編譯器把【public delegate void DisplayStringDelegate(string strmes);】

           編譯為【public class DisplayStringDelegate : MulticastDelegate

        所以,各位客官只要記住 在你定義一個委托類型的時候實際上你是定義了一個類

  • 委托實例函數指針

          先讓我們來看一下這一小節所要用到的示例代碼(所用到的對象類型還是上一小節的內容):

            DisplayStringDelegate disstrdele = newDisplayStringDelegate(newManyMethodClass().InstanceMethod);

            disstrdele += ManyMethodClass.StaticMethod;//這里是委托類型推斷 綁定函數的一種方式 幾種方式可以自行百度

            disstrdele += new DisplayStringDelegate(ManyMethodClass.StaticMethod);

 

 

            1.第一步  在我們執行DisplayStringDelegate disstrdele = newDisplayStringDelegate(newManyMethodClass().InstanceMethod);的時候,disstrdele實例是如下圖一樣:

C#之委托與事件

 

           2.第二步 當我們繼續執行代碼 disstrdele += ManyMethodClass.StaticMethod;的時候,請再來看圖:

C#之委托與事件

           這是disstrdele多指向了一個函數地址,而它的內部實現并不是外表看起來這樣簡單的:

C#之委托與事件

           這里簡要的說一下執行第二步的時候

           L_0012:是將第一步的disstrdele實例壓入棧中

           L_0013:將一個空引用壓入棧中

           L_0014:加載ManyMethodClass.StaticMethod函數地址

           L_001a:實例化DisplayStringDelegate委托類型,假如它叫A

           L_001f:將disstrdele和A合并

           L_0024:將合并好的值轉換成DisplayStringDelegate類型,并且存入L_0013中

           L_0029:將L_0013賦值到disstrdele實例

           (以上純屬個人理解,如有偏差請幫忙糾正,謝謝)

           3.第三步 當我們繼續執行代碼disstrdele += new DisplayStringDelegate(ManyMethodClass.StaticMethod);的時候,過程和第二步相同:

C#之委托與事件

           終上所述,委托實例都會指向一個函數地址,當然嘍合并過后新的委托實例寧當別論,所以 委托實例函數指針 或者委托實例函數指針列表

1.3 委托實例的調用

         我們來看調用的代碼:

          disstrdele("Hello Word");

         這里的內容是接著上一小節的內容繼續講的,拆分開來講是為了讓大家能看的更清楚。

         看一下示意圖吧,

C#之委托與事件

 

C#之委托與事件

        從這里就可以看出來了,雖然disstrdele 實例是合并后的委托實例,它的屁股上掛上了好多函數地址,但是執行這樣函數的入口還只是一個,那就是Delegate.Invoke(string),

        如果有人要問它的Invoke(string)內部是怎么實現的,暫時回答不了,因為具體的代碼是動態生成的吧,不過我們可以自己猜想或者想象一下它是怎么實現的。

        在這里就不多說了。

 

       看了以上的內容能大概的知道或者分清一些概念性的東西。

       這里本人只是講了一把劍是由鐵鑄成的,可以用來切割、刺、劈、砍,至于這把劍怎么用就因人而異了。

2. 事件

2.1 事件是什么?

       這一章我們來學習一下事件

     照舊我們先來看一下示例代碼:

public class EventDomeStration

       {

public EventDomeStration() { }

 /// <summary>

             /// 定義好的一個示例

             /// </summary>

public event DisplayStringDelegate DisplayStringEventHandler;

        }

        在上面的代碼中,我們定義了一個事件DisplayStringEventHandler,而在它名稱前面的是一個DisplayStringDelegate委托類型(就是我們上一節所說的委托)。

        就對于它而言來看一下MSIL,看看它究竟是什么樣的:

        .class public auto ansi beforefieldinit EventDomeStration extends [mscorlib]System.Object

         {

              .field private class DelegateCaseAndEventCase.DisplayStringDelegate DisplayStringEventHandler

              .event DelegateCaseAndEventCase.DisplayStringDelegate DisplayStringEventHandler

              {

                 .addon instance void DelegateCaseAndEventCase.EventDomeStration::add_DisplayStringEventHandler(class DelegateCaseAndEventCase.DisplayStringDelegate) 

                 .removeon instance void DelegateCaseAndEventCase.EventDomeStration::remove_DisplayStringEventHandler(class DelegateCaseAndEventCase.DisplayStringDelegate)

               }

        }

        從這里可以看到,定義好的一個事件就是一個私有(DisplayStringDelegate委托類型)的字段加上一個事件訪問器,也就是相當于C#代碼的這樣:

        public class EventDomeStration

        {

                public EventDomeStration() { }

                private DisplayStringDelegate displaystringdele;

                public event DisplayStringDelegate DisplaystringEventHandler

               {

                     add

                    {

                         displaystringdele += value;

                    }

                    remove

                   {

                        displaystringdele -= value;

                   }

               }

         }

         在這里本人對事件的定義是:

       事件就是所在對象里的屬性,而屬性的類型是委托類型,它是負責架設與外部對象即時通訊(傳遞消息)的橋梁,橋梁本身就是委托。

2.2 事件的使用

         出門在外務工,難免要租房子住,每次找房子是件頭疼的事請各位客官一起來看一下,就拿這個來舉個例子。

         先定義一個委托:publicdelegatevoid消息反饋(string 反饋房子信息);

         首先得有一個中介,暫且叫它為×××中介1, 來看一下它的內部定義:

         public class ×××中介1
         {
              public ×××中介1() { }
              public ×××中介1(string 具體要求)
              {
                   房源信息處理(具體要求);
              }
             public event 消息反饋 消息通知;
             public string 客戶要求的信息_1 = string.Empty;
             private void 房源信息處理(string 客戶要求的信息)
             {
                  //邏輯處理
                  //假如是有客戶需要的 則通知客戶
                 if (消息通知 != null)
                 {
                     消息通知("有房子,什么樣的,信息等等");
                 }
                 客戶要求的信息_1 = 客戶要求的信息;
                 //邏輯處理要是沒有 把信息移交給了中介2
                 ×××中介2 中介2 = new ×××中介2(this);   
              }
              public void 其它中介消息通知(string 房子信息)
              {
                  if (消息通知 != null)
                  {
                      消息通知(房子信息);
                  }
               }
           }

         中介有了,那現在我想要開始租房子怎么辦?沒關系,找中介。

        首先先把“”定義出來:

         public class 

         {

                 //比如我要租房子

                 public 我(){ }

                 public void  我要租房子(string 具體的要求)

                {

                       //找的是×××中介1

                      ×××中介1 中介1 = new ×××中介1(具體的要求);

                      中介1.消息通知 += new 消息反饋(中介1_消息通知);

                 }

                 void 中介1_消息通知(string 房子信息)

                 {

                        //我可以從【房子信息】中知道是否有有合適的房子,如果有得話,是什么樣的

                }

          }

          public class ×××中介2

          {

                public string 客戶要求信息 = string.Empty;

                public ×××中介2() { }

                public ×××中介2(×××中介1 中介1)

                {

                     房源信息處理(中介1);

                }

                private void 房源信息處理(×××中介1 中介1)

               {

                    //邏輯處理

                    //判斷是否有滿足 ->中介1.客戶要求的信息_1值條件的房源

                    //如果有

                   中介1.其它中介消息通知("房子有的,房子的信息等等");

                }

          }

 

          上面定義了 ×××中介1×××中介2,現在 我 要找房子了

          我 me = new ();

           me.我要租房子("有床就行");

          好了,“”已經把信息發布出去了,現在就坐等×××中介1的通知了。

 

          因為事件只能是對象本身內部觸發,這個設計是合理,為什么不能用委托,委托也可以實現同樣的功能啊?

          假如用了委托,這個例子的意思就是“我”可以控制×××中介1有沒有找到房子信息,這個是不符合常理的。

          因為“我”是找的×××中介1×××中介1根據“我”的要求沒找到,把這個信息交給了×××中介2,讓×××中介2幫忙找找,然后中×××中介2找到了,

          但是中×××中介2并不能直接通知“我”,如果可以直接通知的話,這樣“我”會告×××中介1侵犯客戶隱私,

          所以只能是×××中介2告訴×××中介1找到了【也就是代碼:×××中介1.其它中介消息通知("房子有的,房子的信息等等");】,然后再由×××中介1來通知“我”。

 

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

高台县| 巴彦淖尔市| 刚察县| 中卫市| 新绛县| 抚宁县| 根河市| 子洲县| 安乡县| 赤峰市| 西和县| 上饶市| 昌黎县| 仙桃市| 清苑县| 龙川县| 平利县| 扶沟县| 尼玛县| 车险| 铁岭县| 定安县| 常德市| 米林县| 临汾市| 安远县| 张家界市| 琼结县| 商洛市| 大关县| 平远县| 仁怀市| 嘉义县| 孝义市| 同德县| 延安市| 宝鸡市| 永城市| 建平县| 临泽县| 象州县|