• C# 事件相关的练习代码。


    李白 hello!
    李白 再见!
    李白 想你了哈!
    张三 想你了哈!
    Play 没了
    天田田发布了笑脸视频
    键盘侠 说天田田 真年轻,一键三连 666~!
    锅奇侠 说天田田 真漂亮,点赞噢~!
    感谢您使用热水器,现在温度为10,
    本次烧水时间为1分钟。(每分钟提高10摄氏度)
    目前还没烧开!

    感谢您使用热水器,现在温度为10,
    本次烧水时间为10分钟。(每分钟提高10摄氏度)
    叮叮叮,叮叮叮。。。
    报警器提示水壶水温现在是100
    显示器提示现在的水温为100

    CarDealer,new car宝马
    Michael:car 宝马 is new
    CarDealer,new car奔驰
    Michael:car 奔驰 is new
    Nick:car 奔驰 is new
    CarDealer,new car奥迪
    Nick:car 奥迪 is new
    msg:张三 发给 李四消息,内容是:Hello World!
    妈妈 : 饭好了
    爸爸 : 吃饭了。
    孩子 : 打完这局再吃。
    淘宝:发布衣服价格下降的公告,优衣库服装直降200元,限时抢购!
    消费者:之前价格500,现在价格300,果断买了!
    猫叫了一声

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using System.Threading.Tasks;
    6. using C = System.Console;
    7. using System.Reflection;
    8. using noo;
    9. using noo.First;
    10. using System.Threading;
    11. namespace CShape测试
    12. {
    13. internal class AttributeDefineMain
    14. {
    15. static List personList = new List()
    16. {
    17. new Person(){ Id=1,Name="小明",Age=20,Score=100},
    18. new Person(){ Id=2,Name="小王",Age=40,Score=80},
    19. new Person(){ Id=3,Name="小刘",Age=60,Score=60}
    20. };
    21. public delegate void SayHelloOlg(string name);
    22. public static void SayHello(string name)
    23. {
    24. Console.WriteLine($"{name} hello!");
    25. }
    26. public static void SayBye(string name)
    27. {
    28. Console.WriteLine($"{name} 再见!");
    29. }
    30. public static event SayHelloOlg SayHelloEvent;
    31. public static void Main()
    32. {
    33. //AttributeDefineExamle model = new AttributeDefineExamle();
    34. //Type type = model.GetType();
    35. //if (type.IsDefined(typeof(AttributeDefineDemo), true))
    36. //{
    37. // var attribute = type.GetCustomAttribute();
    38. // if (attribute.IsAge())
    39. // {
    40. // model.Show();
    41. // }
    42. //}
    43. //MethodInfo method = model.GetType().GetMethod("Show");
    44. //if (method.IsDefined(typeof(AttributeDefineDemo), true))
    45. //{
    46. // var attribute = method.GetCustomAttribute();
    47. // if (attribute.IsAge())
    48. // {
    49. // model.Show();
    50. // }
    51. //}
    52. //int num = MathAdd.Muti(12, 13);
    53. //MathAdd mathAdd = new MathAdd();
    54. //int num1 = mathAdd.Add(12, 12);
    55. IEnumerable
    56. var list = personList.Where((p) => p.Age < 50);
    57. var list = personList.Select(p => p.Name);
    58. //var list = personList.Select(p => new { id = p.Id, name = p.Name });
    59. //foreach (var tmp in list)
    60. //{
    61. // C.WriteLine(tmp);
    62. //}
    63. // 委托声明
    64. //委托的使用方法
    65. //委托的解释:将方法以变量的方式传递,并以方法的形式执行
    66. SayHelloOlg dlg = SayHello;
    67. dlg += SayBye;
    68. dlg += (string str) => Console.WriteLine($"{str} 想你了哈!");
    69. dlg("李白");
    70. //事件,是被限制的委托
    71. SayHelloEvent += AttributeDefineMain_SayHelloEvent;
    72. if (SayHelloEvent != null)
    73. {
    74. SayHelloEvent("张三");
    75. }
    76. //有利于 高内聚,低耦合
    77. // 事件的组成
    78. // 事件拥有者 事件成员 事件响应者 事件处理器 事件订阅
    79. //玩家 死亡==UI显示死亡
    80. // 玩家:事件拥有者 死亡:事件成员 UI:事件的响应者 显示死亡:事件处理器 桥梁:事件订阅 (只有订阅了的玩家才可以发生事件)
    81. /*
    82. Play
    83. {
    84. UI.WhenPlayDie();
    85. }
    86. UI
    87. {
    88. WhenPlayDie()
    89. {
    90. do some thing
    91. }
    92. }
    93. */
    94. Player player = new Player();
    95. UI ui = new UI(player);
    96. if (player.hp <= 0)
    97. player.OnGUI();
    98. player.hp -= 200;
    99. if (player.hp <= 0)
    100. player.OnGUI();
    101. /*
    102. up主发动态, 粉丝响应
    103. */
    104. Up up = new Up("天田田","笑脸视频");
    105. Fans fans1 = new Fans("键盘侠");
    106. Fans fans2 = new Fans("锅奇侠");
    107. up.publish += fans1.jianpanComment;
    108. up.publish += fans2.guoqixiaComment;
    109. up.OnPublish();//发布
    110. /*
    111. 闹钟 响了 我 起床
    112. 孩子 饿了 你 做饭
    113. 隐含 订阅
    114. 发生,响应模型
    115. 事件拥有者 事件成员 事件响应者 事件处理器 事件订阅
    116. 烧水 开了==报警器 报警
    117. */
    118. Heater he1 = new Heater(); //第一次烧水(水没烧开,不会触发事件)
    119. he1.Temperature = 10;
    120. Alarm al1 = new Alarm();
    121. Display di1 = new Display();
    122. he1.DoMyAlarm += al1.MakeAlert; //建立关联
    123. he1.DoMyDisplay += di1.ShowMsg; //建立关联
    124. he1.BoilWater(1);
    125. Heater he2 = new Heater(); //第二次烧水(水烧开,触发显示与报警事件)
    126. he2.Temperature = 10;
    127. Alarm al2 = new Alarm();
    128. Display di2 = new Display();
    129. he2.DoMyAlarm += al2.MakeAlert; //建立关联
    130. he2.DoMyDisplay += di2.ShowMsg; //建立关联
    131. he2.BoilWater(10);
    132. CarDealer dealer = new CarDealer();
    133. Consumer michael = new Consumer("Michael");
    134. dealer.NewCardInfo += michael.NewCarIsHere; //订阅事件
    135. dealer.NewCar("宝马");
    136. Consumer nick = new Consumer("Nick");
    137. dealer.NewCardInfo += nick.NewCarIsHere; //订阅事件
    138. dealer.NewCar("奔驰");
    139. dealer.NewCardInfo -= michael.NewCarIsHere; //取消订阅事件
    140. dealer.NewCar("奥迪");
    141. MailManager mm = new MailManager();
    142. Fax f = new Fax(mm);
    143. mm.SimulateNewMail("张三", "李四", "Hello World!");
    144. //实例化对象
    145. Mom mom = new Mom();
    146. Dad dad = new Dad();
    147. Child child = new Child();
    148. //将爸爸和孩子的Eat方法注册到妈妈的Eat事件
    149. //订阅妈妈开饭的消息
    150. mom.Eat += dad.Eat;
    151. mom.Eat += child.Eat;
    152. //调用妈妈的Cook事件
    153. mom.Cook();
    154. EventStandard.Show();
    155. Cat cat = new Cat();
    156. Mouse mouse = new Mouse(cat);
    157. People people = new People(cat);
    158. cat.Scream();
    159. /*
    160. 事件: 能够发生的什么事情
    161. 事件: 是类的成员
    162. 事件发生的效果,就是对象的功能【通知能力】 就是通知
    163. */
    164. Console.Write("Press any key to continue . . . ");
    165. C.ReadKey();
    166. }
    167. #region
    168. /*服装价格变动,触发淘宝发布活动和消费者购买衣服事件流*/
    169. public class EventStandard
    170. {
    171. public class Clothes
    172. {
    173. ///
    174. /// 服装编码
    175. ///
    176. public string Id { get; set; }
    177. ///
    178. /// 服装名称
    179. ///
    180. public string Name { get; set; }
    181. ///
    182. /// 服装价格
    183. ///
    184. private double _price;
    185. public double Price
    186. {
    187. get { return this._price; }
    188. set
    189. {
    190. PriceRiseHandler?.Invoke(this, new PriceEventArgs()
    191. {
    192. OldPrice = this._price,
    193. NewPrice = value
    194. });
    195. this._price = value;
    196. }
    197. }
    198. ///
    199. /// 服装价格变动事件
    200. ///
    201. public event EventHandler PriceRiseHandler;
    202. }
    203. ///
    204. /// 衣服价格事件参数 一般会为特定的事件去封装个参数类型
    205. ///
    206. public class PriceEventArgs : EventArgs
    207. {
    208. public double OldPrice { get; set; }
    209. public double NewPrice { get; set; }
    210. }
    211. public class TaoBao
    212. {
    213. ///
    214. /// 淘宝订户
    215. ///
    216. public void PublishPriceInfo(object sender, EventArgs e)
    217. {
    218. Clothes clothes = (Clothes)sender;
    219. PriceEventArgs args = (PriceEventArgs)e;
    220. if (args.NewPrice < args.OldPrice)
    221. Console.WriteLine($"淘宝:发布衣服价格下降的公告,{clothes.Name}服装直降{args.OldPrice - args.NewPrice}元,限时抢购!");
    222. else
    223. Console.WriteLine("淘宝:价格悄悄上涨或价格未变化,啥也不做");
    224. }
    225. }
    226. public class Consumer
    227. {
    228. ///
    229. /// 消费者订户
    230. ///
    231. public void Buy(object sender, EventArgs e)
    232. {
    233. Clothes clothes = (Clothes)sender;
    234. PriceEventArgs args = (PriceEventArgs)e;
    235. if (args.NewPrice < args.OldPrice)
    236. Console.WriteLine($"消费者:之前价格{args.OldPrice},现在价格{args.NewPrice},果断买了!");
    237. else
    238. Console.WriteLine($"消费者:等等看,降价了再说");
    239. }
    240. }
    241. public static void Show()
    242. {
    243. Clothes clothes = new Clothes()
    244. {
    245. Id = "12111-XK",
    246. Name = "优衣库",
    247. Price = 500
    248. };
    249. //订阅:把订户和发布者的事件关联起来
    250. clothes.PriceRiseHandler += new TaoBao().PublishPriceInfo;
    251. clothes.PriceRiseHandler += new Consumer().Buy;
    252. //价格变化,自动触发订户订阅的事件
    253. clothes.Price = 300;
    254. }
    255. }
    256. #endregion
    257. // 经典面试题,猫叫、老鼠跑了,主人醒来了
    258. public delegate void ScreamHandler();
    259. public class Cat
    260. {
    261. public event ScreamHandler OnScream;
    262. public void Scream()
    263. {
    264. C.WriteLine("猫叫了一声");
    265. OnScream?.Invoke();
    266. }
    267. }
    268. public class Mouse
    269. {
    270. public Mouse(Cat c)
    271. {
    272. c.OnScream += () =>
    273. {
    274. C.WriteLine("老鼠跑了");
    275. };
    276. }
    277. }
    278. public class People
    279. {
    280. public People(Cat c)
    281. {
    282. c.OnScream += () =>
    283. {
    284. C.WriteLine("主人醒来了");
    285. };
    286. }
    287. }
    288. #region
    289. /*
    290. 我们用一个简单的例子,来说明一下这种消息传递的机制。
    291.    有一家三口,妈妈负责做饭,爸爸和孩子负责吃。。。将这三个人,想象成三个类。
    292.    妈妈有一个方法,叫做“做饭”。有一个事件,叫做“开饭”。做完饭后,调用开发事件,发布开饭消息。
    293.    爸爸和孩子分别有一个方法,叫做“吃饭”。
    294.    将爸爸和孩子的“吃饭”方法,注册到妈妈的“开饭”事件。也就是,订阅妈妈的开饭消息。让妈妈做完饭开饭时,发布吃饭消息时,告诉爸爸和孩子一声。
    295. */
    296. public class Mom
    297. {
    298. //定义Eat事件,用于发布吃饭消息
    299. public event Action Eat;
    300. public void Cook()
    301. {
    302. Console.WriteLine("妈妈 : 饭好了");
    303. //饭好了,发布吃饭消息
    304. Eat?.Invoke();
    305. }
    306. }
    307. public class Dad
    308. {
    309. public void Eat()
    310. {
    311. //爸爸去吃饭
    312. Console.WriteLine("爸爸 : 吃饭了。");
    313. }
    314. }
    315. public class Child
    316. {
    317. public void Eat()
    318. {
    319. //熊孩子LOL呢,打完再吃
    320. Console.WriteLine("孩子 : 打完这局再吃。");
    321. }
    322. }
    323. #endregion
    324. #region
    325. ///
    326. /// 事件附加消息
    327. ///
    328. public class NewMailEventArgs : EventArgs
    329. {
    330. private readonly string m_from, m_to, m_subject;
    331. public NewMailEventArgs(string from, string to, string subject)
    332. {
    333. m_from = from;
    334. m_to = to;
    335. m_subject = subject;
    336. }
    337. // 发件人
    338. public string From { get { return m_from; } }
    339. // 接收人
    340. public string To { get { return m_to; } }
    341. // 主题
    342. public string Subject { get { return m_subject; } }
    343. }
    344. public class MailManager
    345. {
    346. // 定义事件成员
    347. public event EventHandler NewMail;
    348. // 定义负责引发事件的方法来通知已登记的对象
    349. protected virtual void OnNewMail(NewMailEventArgs e)
    350. {
    351. // 将字段复制到一个临时变量,避免多线程情况中这个成员被移除
    352. EventHandler temp = Volatile.Read(ref NewMail);
    353. // if (temp != null) temp(this, e);
    354. temp?.Invoke(this,e);
    355. }
    356. // 接受附加信息并调用引发事件的方法来通知所有登记的对象
    357. public void SimulateNewMail(string from, string to, string subject)
    358. {
    359. NewMailEventArgs e = new NewMailEventArgs(from, to, subject);
    360. OnNewMail(e);
    361. }
    362. }
    363. public class Fax
    364. {
    365. public Fax(MailManager mm)
    366. {
    367. // 构造委托实例,向事件登记回调方法
    368. mm.NewMail += FaxMsg;
    369. }
    370. ///
    371. /// 回调方法
    372. ///
    373. /// 表示MailManager对象,便于将信息传递给他
    374. /// 表示MailManager对象想传给我们的附加信息
    375. private void FaxMsg(object sender, NewMailEventArgs e)
    376. {
    377. Console.WriteLine("msg:{0} 发给 {1}消息,内容是:{2}", e.From, e.To, e.Subject);
    378. }
    379. ///
    380. /// 注销对事件的登记
    381. ///
    382. ///
    383. public void Unregister(MailManager mm)
    384. {
    385. mm.NewMail -= FaxMsg;
    386. }
    387. }
    388. #endregion
    389. #region 测试事件1
    390. //EventArgs类
    391. public class CardInfoEventArgs : EventArgs
    392. {
    393. public string Car { get; private set; }
    394. public CardInfoEventArgs(string car)
    395. {
    396. this.Car = car;
    397. }
    398. }
    399. //触发事件的类
    400. public class CarDealer
    401. {
    402. public event EventHandler NewCardInfo;
    403. public void NewCar(string car)
    404. {
    405. Console.WriteLine("CarDealer,new car{0}", car);
    406. //在触发事件之前,需要检查委托NewCardInfo是否不为空。如果没有订阅处理程序,委托就是空
    407. if (NewCardInfo != null)
    408. {
    409. NewCardInfo(this, new CardInfoEventArgs(car));
    410. }
    411. }
    412. }
    413. //处理事件的类
    414. public class Consumer
    415. {
    416. private string name;
    417. public Consumer(string name)
    418. {
    419. this.name = name;
    420. }
    421. //处理事件的方法
    422. public void NewCarIsHere(object sender, CardInfoEventArgs e)
    423. {
    424. Console.WriteLine("{0}:car {1} is new", name, e.Car);
    425. }
    426. }
    427. #endregion
    428. //public delegate void MyAlarm(int temperature); //创建委托报警
    429. //public delegate void MyDispaly(int temperature); //创建委托显示
    430. class Heater
    431. {
    432. // public event MyAlarm DoMyAlarm; //建立事件报警
    433. // public event MyDispaly DoMyDisplay; //建立事件显示
    434. public event EventHandler DoMyAlarm;
    435. public event EventHandler DoMyDisplay;
    436. private int temperature; //温度
    437. public int Temperature
    438. {
    439. get { return temperature; }
    440. set
    441. {
    442. if ((temperature >= 0) && (temperature <= 100))
    443. temperature = value;
    444. else
    445. Console.WriteLine("温度有问题!显示出错!");
    446. }
    447. }
    448. public void BoilWater(int m) //m 表示烧水时间,没分钟提高摄氏度
    449. {
    450. Console.WriteLine("感谢您使用热水器,现在温度为{0},\n本次烧水时间为{1}分钟。" +
    451. "(每分钟提高10摄氏度)", this.temperature, m);
    452. this.temperature = m * 10 + this.temperature;
    453. if (this.temperature >= 100)
    454. this.temperature = 100;
    455. if (this.temperature >= 95)
    456. {
    457. if(DoMyAlarm!=null)
    458. DoMyAlarm(this, new My_EventArgs(this.temperature));
    459. if(DoMyDisplay!=null)
    460. DoMyDisplay(this, new My_EventArgs(this.temperature));
    461. Console.WriteLine("");
    462. }
    463. else
    464. Console.WriteLine("目前还没烧开!\n");
    465. }
    466. }
    467. class My_EventArgs : EventArgs
    468. {
    469. public int temperature;
    470. public My_EventArgs(int temperature)
    471. {
    472. this.temperature = temperature;
    473. }
    474. }
    475. class Alarm //报警器类
    476. {
    477. public void MakeAlert(object o,EventArgs eventargs)
    478. {
    479. My_EventArgs e = (My_EventArgs)eventargs;
    480. Console.WriteLine("叮叮叮,叮叮叮。。。\n报警器提示水壶水温现在是{0}", e.temperature);
    481. }
    482. }
    483. class Display //显示器类
    484. {
    485. public void ShowMsg(object o, EventArgs eventargs)
    486. {
    487. My_EventArgs e = (My_EventArgs)eventargs;
    488. Console.WriteLine("显示器提示现在的水温为{0}", e.temperature);
    489. }
    490. }
    491. class MyEventArgs :EventArgs
    492. {
    493. public string name,content;
    494. }
    495. class Up
    496. {
    497. public event EventHandler publish;// 委托字段 event 必须持有,如果不持有,publish不是真正意义上的事件,会被强行调用。起安全作用
    498. //事件就是委托的限定器。限制所有的功能。
    499. //除了订阅 和取消订阅
    500. string name;
    501. string content;//发布内容
    502. public Up(string name, string content) { this.name = name; this.content = content; }
    503. public void OnPublish()
    504. {
    505. C.WriteLine($"{name }发布了{content}");
    506. MyEventArgs args = new MyEventArgs();
    507. args.name = name;
    508. args.content = content;
    509. publish(name,args);
    510. }
    511. }
    512. class Fans
    513. {
    514. string name;
    515. string comment;
    516. public Fans(string name) { this.name = name;}
    517. internal void guoqixiaComment(object upName, EventArgs content)
    518. {
    519. C.WriteLine($"{this.name}{upName} 真漂亮,点赞噢~!");
    520. }
    521. internal void jianpanComment(object upName, EventArgs content)
    522. {
    523. C.WriteLine($"{this.name}{upName} 真年轻,一键三连 666~!");
    524. }
    525. }
    526. public class Player
    527. {
    528. public delegate void ClickAction();
    529. public event ClickAction Death;
    530. public int hp;
    531. public Player()
    532. {
    533. hp = 100;
    534. }
    535. public void OnGUI()
    536. {
    537. Death();
    538. }
    539. }
    540. public class UI
    541. {
    542. private readonly Player Player;
    543. public UI(Player player)
    544. {
    545. Player = player;
    546. Player.Death += DeathHandler;
    547. }
    548. ~UI()
    549. {
    550. Player.Death -= DeathHandler;
    551. }
    552. void DeathHandler()
    553. {
    554. C.WriteLine("Play 没了");
    555. }
    556. }
    557. private static void AttributeDefineMain_SayHelloEvent(string name)
    558. {
    559. Console.WriteLine($"{name} 想你了哈!");
    560. }
    561. }
    562. class Person
    563. {
    564. public int Id, Age, Score;
    565. public string Name;
    566. public override string ToString()
    567. {
    568. return base.ToString() + " " + Id + "," + Name + "," + Age + "," + Score;
    569. }
    570. }
    571. }

  • 相关阅读:
    【物理】斜面交点之处机械能/动量损失问题
    【老生谈算法】matlab实现图像阈值分割算法——图像阈值分割
    我为什么要推荐用Stream语法
    css的rotate3d实现炫酷的圆环转动动画
    Word控件Spire.Doc 【图像形状】教程(3) :在 C#/VB.NET 中的指定位置插入图像
    艾美捷ICT FLICA天冬氨酸蛋白酶(Caspase)活性检测试剂盒说明书
    C++ vector 的使用
    200篇纪念总结
    算法基础——时间复杂度和空间复杂度
    技术对接50
  • 原文地址:https://blog.csdn.net/laocooon/article/details/126018403