日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

part01.04 事件

發(fā)布時(shí)間:2025/3/15 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 part01.04 事件 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

  1. C#事件的概念

C# 中時(shí)間允許一個(gè)對(duì)象將發(fā)生的事件通知其他對(duì)象,將發(fā)生的事件的事件源叫發(fā)行者,通知其他的對(duì)象叫訂閱者,但是訂閱者可以定義也可以不定義(事件發(fā)生者也可以是事件的訂閱者)

1 class Program 2 { 3 static void Main(string[] args) 4 { 5 var user = new User(); 6 user.Name = "xiaohon"; 7 user.Password = "123"; 8 9 user.EventLogin += new User.DelegateLogin(User_EventLogin); 10 user.Login(); 11 12 } 13 14 private static void User_EventLogin() 15 { 16 Console.WriteLine("login seccessful"); 17 } 18 } 19 20 class User 21 { 22 public delegate void DelegateLogin(); // 定義一個(gè)委托 23 public event DelegateLogin EventLogin; // 定義一個(gè)事件(事件用關(guān)鍵字加委托名來(lái)定的且后面無(wú)括號(hào)) 24 25 public string Name { get; set; } 26 public string Password { get; set; } 27 28 /// <summary> 29 /// 類的方法(可做為方法的參數(shù)即委托) 30 /// </summary> 31 public void Login() 32 { 33 Console.WriteLine("Login....."); 34 35 // 引發(fā)事件 36 if (EventLogin != null) 37 { 38 EventLogin(); 39 } 40 } 41 } View Code

2. 事件的聲明

。事件是成員,它必須聲明在類或類型中,和其他成員一樣。

。由于事件不是類型,我們不能像委托那樣使用對(duì)象創(chuàng)建表達(dá)式(new 表達(dá)式)來(lái)創(chuàng)建它的對(duì)象。

。事件成員被隱式自動(dòng)初始化為 null 。

3. 委托類型和 EventHandler

。事件聲明需要委托類型的名字,我們可以聲明一個(gè)委托類型或使用已存在的。聲明一個(gè)委托類型,它必須指定事件保存的方法的簽名和返回類型。

。更好的方案就是使用 EventHandler 委托。

4. 觸發(fā)事件

。在觸發(fā)事件之前和 null 進(jìn)行比較,從而查看是否包含任何事件處理程序,如果事件是 null ,則表示沒有。

。出發(fā)事件本身看起來(lái)像調(diào)用函數(shù)一樣。

5. 訂閱事件

。使用 += 運(yùn)算符來(lái)添加事件處理程序(即綁定多個(gè)方法),方法可以是:

  。實(shí)例方法

  。靜態(tài)方法

  。匿名方法

  。Lambda 表達(dá)式

。使用 -= 運(yùn)算符來(lái)移除事件處理程序(即刪除多個(gè)方法)

6. 關(guān)于 EventArg 類

?。EventArgs 被設(shè)計(jì)為不能專遞任何數(shù)據(jù)。它用于不需要傳遞數(shù)據(jù)的事件處理程序。

。通過(guò)擴(kuò)展 EventArgs 來(lái)傳遞數(shù)據(jù)。

7. 觀察者(Observer)設(shè)計(jì)模式的一種實(shí)現(xiàn)

熱水器,加電燒水,當(dāng)水溫超過(guò) 95 度的時(shí)候:
  1. 揚(yáng)聲器會(huì)開始 發(fā)出語(yǔ)音,告訴你水的溫度;
  2. 液晶屏也會(huì)改變水溫的顯示,來(lái)提示水已經(jīng)快燒開了。
如何在水快燒開的時(shí)候通知報(bào)警器和顯示器?

?

1. 警報(bào)器和顯示器告訴熱水器,它對(duì)它的溫度比較感興趣(注冊(cè))。
2. 熱水器知道后保留對(duì)警報(bào)器和顯示器的引用。
3. 熱水器進(jìn)行燒水這一動(dòng)作,當(dāng)水溫超過(guò) 95 度時(shí),通過(guò)對(duì)警報(bào)器和顯示器的引用,自動(dòng) 調(diào)用警報(bào)器的 MakeAlert()方法、顯示器的 ShowMsg()方法

。Observer 設(shè)計(jì)模式:Observer 設(shè)計(jì) 模式是為了定義對(duì)象間的一種一對(duì)多的依賴關(guān)系,以便于當(dāng)一個(gè)對(duì)象的狀態(tài)改變時(shí),其他依賴 于它的對(duì)象會(huì)被自動(dòng)告知并更新。Observer 模式是一種松耦合的設(shè)計(jì)模式
。Observer 設(shè)計(jì)模式中主要包括如下兩類對(duì)象:
  。Subject:監(jiān)視對(duì)象,它往往包含著其他對(duì)象所感興趣的內(nèi)容。在本范例中,熱水器就是一個(gè)監(jiān)視對(duì)象,它包含的其他對(duì)象所感興趣的內(nèi)容,就是 temperature 屬性,當(dāng)這個(gè)屬性的值快到 100 時(shí),會(huì)不斷把數(shù)據(jù)發(fā)給監(jiān)視它的對(duì)象。
  。Observer:觀察者,它監(jiān)視 Subject,當(dāng) Subject 中的某件事發(fā)生的時(shí)候,會(huì)告知 Observer,而 Observer 則會(huì)采取相應(yīng)的行動(dòng)。在本范例中,Observer 有警報(bào)器和顯示器,它們采取的行動(dòng)分別是發(fā)出警報(bào)和顯示水溫。

常規(guī)的實(shí)現(xiàn):

1 class Program 2 { 3 static void Main(string[] args) 4 { 5 var heater = new Heater(); // 創(chuàng)建熱水器對(duì)象 6 var alarm = new Alarm(); // 創(chuàng)建報(bào)警器對(duì)象 7 8 heater.BoilEvent += alarm.MakeAlarm; // 注冊(cè)報(bào)警方法 9 heater.BoilEvent += (new Alarm()).MakeAlarm; // 給匿名對(duì)象注冊(cè)方法 10 heater.BoilEvent += Display.ShowMsg; // 注冊(cè)靜態(tài)方法 11 12 heater.BoilWater(); // 開始燒水,根據(jù)方法的條件會(huì)自動(dòng)調(diào)用注冊(cè)的方法 13 14 Console.ReadKey(); 15 } 16 } 17 18 /// <summary> 19 /// 熱水器 20 /// </summary> 21 class Heater 22 { 23 private int temperature; // 溫度 24 public delegate void BoilHandler(int temp); // 聲明委托 25 public event BoilHandler BoilEvent; // 聲明事件 26 27 /// <summary> 28 /// 燒水 29 /// </summary> 30 public void BoilWater() 31 { 32 for(int i = 95; i <= 100; i++) 33 { 34 temperature = i; 35 if (temperature > 95) 36 { 37 // 如果定義的事件有對(duì)象注冊(cè) 38 if(BoilEvent != null) 39 { 40 // 則執(zhí)行其中的所有方法 41 BoilEvent(temperature); 42 } 43 } 44 } 45 } 46 } 47 48 /// <summary> 49 /// 溫度顯示器 50 /// </summary> 51 class Display 52 { 53 /// <summary> 54 /// 顯示方法 55 /// </summary> 56 /// <param name="temp">溫度</param> 57 public static void ShowMsg(int temp) 58 { 59 Console.WriteLine("顯示器:水快燒開了,當(dāng)前溫度是{0}度", temp); 60 } 61 } 62 63 /// <summary> 64 /// 報(bào)警器 65 /// </summary> 66 class Alarm 67 { 68 /// <summary> 69 /// 報(bào)警方式 70 /// </summary> 71 /// <param name="temp">溫度</param> 72 public void MakeAlarm(int temp) 73 { 74 Console.WriteLine("當(dāng)前溫度是" + temp + ""); 75 } 76 } 常規(guī)的實(shí)現(xiàn)

8. .Net Framework 中的委托和事件

1. 委托類型的名稱都應(yīng)該以 EventHandler 結(jié)束。

2. 委托的原型定義:有一個(gè) void 返回值,并接受兩個(gè)輸入?yún)?shù):一個(gè) Object 類型,一個(gè) EventArgs 類型(或繼承自 EventArgs)。

3. 事件的命名為委托去掉 EventHandler 之后剩余的部分。

4. 繼承自 EventArgs 的類型應(yīng)該以 EventArgs 結(jié)尾。

5. 委托聲明原型中的 Object 類型的參數(shù)代表了 Subject ,也就是監(jiān)視對(duì)象,在本例中是 Heater(熱水器)。回調(diào)函數(shù)(比如 Alarm 的MakeAlert)可以通過(guò)它訪問(wèn)觸發(fā)事件的對(duì)象(Heater)。

6. EventArgs 對(duì)象包含了 Observer 所感興趣的數(shù)據(jù),在本例中是 temperature。

改進(jìn)后的代碼:

?

1 class Program 2 { 3 static void Main(string[] args) 4 { 5 var heater = new Heater(); // 創(chuàng)建熱水器對(duì)象 6 var alarm = new Alarm(); // 創(chuàng)建報(bào)警器對(duì)象 7 8 //heater.BoilEvent += alarm.MakeAlarm; // 注冊(cè)報(bào)警方法 9 //heater.BoilEvent += (new Alarm()).MakeAlarm; // 給匿名對(duì)象注冊(cè)方法 10 11 heater.Boiled += Display.ShowMsg; // 注冊(cè)靜態(tài)方法 12 heater.Boiled += new Heater.BoilEventHandler(alarm.MakeAlarm); // 另一種注冊(cè)方式 13 14 heater.BoilWater(); // 開始燒水,根據(jù)方法的條件會(huì)自動(dòng)調(diào)用注冊(cè)的方法 15 16 Console.ReadKey(); 17 } 18 } 19 20 /// <summary> 21 /// 熱水器 22 /// </summary> 23 class Heater 24 { 25 private int _Temperature; // 溫度 26 public string Brand = "格星 X-1219"; 27 public string Manufacturer = "xx 格星電器有限責(zé)任公司"; 28 29 // 委托的原型定義:有一個(gè) void 返回值,并接受兩個(gè)輸入?yún)?shù):一個(gè) Object 類型, 一個(gè) EventArgs 類型(或繼承自 EventArgs) 30 public delegate void BoilEventHandler(object sender,BoiledEventArgs e); // 聲明委托 委托類型的名稱都應(yīng)該以 EventHandler 結(jié)束 31 public event BoilEventHandler Boiled; // 聲明事件 事件的命名為委托去掉 EventHandler 之后剩余的部分 32 33 /// <summary> 34 /// 構(gòu)建一個(gè)可以重寫的方法,以便它的派生類拒絕其他對(duì)象的訪問(wèn) 35 /// </summary> 36 /// <param name="e">事件參數(shù)</param> 37 protected virtual void OnBoiled(BoiledEventArgs e) 38 { 39 if(Boiled != null) 40 { 41 Boiled(this, e); 42 } 43 } 44 45 /// <summary> 46 /// 燒水 47 /// </summary> 48 public void BoilWater() 49 { 50 for(int i = 95; i <= 100; i++) 51 { 52 _Temperature = i; 53 if (_Temperature > 95) 54 { 55 BoiledEventArgs e = new BoiledEventArgs(_Temperature); 56 OnBoiled(e); 57 } 58 } 59 } 60 } 61 62 /// <summary> 63 /// 定義一個(gè)事件參數(shù)類,用于承載需要傳遞給 Observer 所感興趣的信息 64 /// 繼承自 EventArgs 的類型應(yīng)該以 EventArgs 結(jié)尾 65 /// EventArgs 對(duì)象包含了 Observer 所感興趣的數(shù)據(jù),在本例中是 _Temperature 66 /// </summary> 67 public class BoiledEventArgs : EventArgs 68 { 69 public readonly int _Temperature; 70 71 public BoiledEventArgs(int temp) 72 { 73 this._Temperature = temp; 74 } 75 } 76 77 /// <summary> 78 /// 溫度顯示器 79 /// </summary> 80 class Display 81 { 82 /// <summary> 83 /// 顯示方法 84 /// </summary> 85 /// <param name="temp">溫度</param> 86 public static void ShowMsg(object sender,BoiledEventArgs e) 87 { 88 var obj = sender as Heater; 89 Console.WriteLine("顯示器{0}({1})", obj.Brand, obj.Manufacturer); 90 Console.WriteLine("顯示器:水快燒開了,當(dāng)前溫度是{0}度", e._Temperature); 91 } 92 } 93 94 /// <summary> 95 /// 報(bào)警器 96 /// </summary> 97 class Alarm 98 { 99 /// <summary> 100 /// 報(bào)警方式 101 /// </summary> 102 /// <param name="temp">溫度</param> 103 public void MakeAlarm(object sender,BoiledEventArgs e) 104 { 105 Console.WriteLine("當(dāng)前溫度是" + e._Temperature + ""); 106 } 107 } 改進(jìn)后的代碼

?

?

?

?

參考網(wǎng)址:https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/events/

?

轉(zhuǎn)載于:https://www.cnblogs.com/huangzewei/p/7300080.html

總結(jié)

以上是生活随笔為你收集整理的part01.04 事件的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。