关键词搜索

源码搜索 ×
×

C#基础学习--事件

发布2023-04-16浏览597次

详情内容

目录

发布者和订阅者

 源代码组件概览

 声明事件

事件是成员

订阅事件

 触发事件

 标准事件的用法

 通过扩展EventArgs来传递数据

泛型委托

 移除事件处理程序  -=

事件访问器


发布者和订阅者

发布者/订阅者模式中,发布者类 定义了一系列程序的其他部分可能感兴趣的事件。其他类可以“注册”,以便在这些事件发生时发布者可以通知它们。这些 订阅者类 通过向发布者提供一个方法来“注册”以获取通知。当事件发生时,发布者 “触发事件” ,然后执行订阅者提交的所有事件

由订阅者提供的方法称为 回调方法 ,因为发布者通过执行这些方法来 “往回调用订阅者的方法”,还可以将他们称为 事件处理程序,因为它们是为处理事件而调用的代码。

 一些有关事件的重要事项:

 事件的私有委托:

     事件提供了对它的私有控制委托的结构化访问。也就是说,你无法直接访问委托

      事件中可用的操作比委托少,对于事件我们只可以添加,删除或调用事件处理程序。

     事件被触发时,他调用委托来依次调用调用列表中的方法

+=  和 -= 运算符是事件唯一允许的操作(除了调用事件本身)

 源代码组件概览

需要在事件中使用的代码有5部分:

委托类型声明 事件和事件处理程序必须有共同的签名和返回类型,它们通过委托类型进行描述

事件处理程序声明   订阅者类中会在事件触发时执行的方法声明。它们不一定是有显式命名的方法,还可以是匿名方法或者Lambda 表达式

事件声明  发布者类必须声明一个订阅者可以注册的事件成员。当声明的事件为public时,称为发布了事件

事件注册   订阅者必须订阅事件才能在它被触发时得到通知

触发事件的代码   发布者类中“ 触发 ”事件并导致调用注册的所有事件处理程序的代码

 声明事件

事件声明在一个类中

它需要委托类型的名称,任何附加到事件(如注册)的处理程序都必须与委托类型的签名和返回类型匹配

它声明为public,这样其他类和结构可以在它上面注册事件处理程序

不能使用对象创建表达式(new表达式)来创建它的对象

 可以通过逗号分隔的列表在一个声明语句中声明一个以上的事件

 可以使用 static 关键字让事件变成静态

事件是成员

由于事件是成员:

    我们不能在一段可执行代码中声明事件

    它必须声明在类或结构中,和其他成员一样

事件成员被隐式自动初始化为null

订阅事件

对于一个要添加到事件的事件处理程序来说,它必须具有与事件的委托相同的返回类型和签名

使用 += 运算符来为事件增加事件处理程序

 触发事件

事件成员本身只是保存了需要被调用的事件处理程序。如果时间没有被触发就什么都不会发生

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. namespace Csharpzuoye
  5. {
  6. delegate void Handler();
  7. //发布者:
  8. class Incrementer
  9. {
  10. public event Handler CountedADozen; //创建事件并发布
  11. public void DoCount()
  12. {
  13. for(int i = 1;i<100;i++)
  14. {
  15. if (i % 12 == 0 && CountedADozen != null)
  16. CountedADozen(); //每增加12个计数触发事件一次
  17. }
  18. }
  19. }
  20. //订阅者:
  21. class Dozens
  22. {
  23. public int DozensCount { get; private set; }
  24. //构造函数
  25. public Dozens(Incrementer incrementer)
  26. {
  27. DozensCount = 0;
  28. incrementer.CountedADozen += IncrementDozensCount; //订阅事件
  29. }
  30. //声明事件处理程序
  31. void IncrementDozensCount()
  32. {
  33. DozensCount++;
  34. }
  35. }
  36. class Program
  37. {
  38. static void Main()
  39. {
  40. Incrementer incrementer = new Incrementer();
  41. //构造函数直接订阅事件,一步到位
  42. Dozens dozensCounter = new Dozens(incrementer);
  43. incrementer.DoCount();
  44. Console.WriteLine("Number of dozens = {0}", dozensCounter.DozensCount);
  45. }
  46. }
  47. }

 标准事件的用法

GUI编程是事件驱动的,也就是说在程序运行时,它可以在任何时候被事件打断,比如按钮点击,按下按键或系统定时器

 事件使用的标准模式的根本就是System命名空间声明的EventHandler委托类型。

 EventHandler 委托类型的第二个参数是EventArgs类对象,它的声明在System命名空间中

 不管参数使用什么的实际类型是什么,object类和EventArgs总是基类,这样EventHandler就能提供一个对所有事件和事件处理器都通用的签名,只允许两个参数,而不是各自都有不同的签名

标准使用对比:

 通过扩展EventArgs来传递数据

声明一个派生自EventArgs的自定义类,可以保存我们传入的数据,向事件处理程序的第二个参数传入数据

类的名称应该以EventArgs结尾

泛型委托

 移除事件处理程序  -=

事件访问器

 

相关技术文章

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载