• C#-事件的详细用法


    什么是事件

    事件(Event) 基本上说是一个用户操作,如按键、点击、鼠标移动等等,或者是一些 提示信息,如系统生成的通知。应用程序需要在事件发生时响应事件。例如,中断。

    C#中使用事件机制实现线程间的通信。

    事件的处理需要委托实现来调度事件,所以事件和委托是紧密关联的(耦合性高)

    通过事件使用委托

    事件在类中声明且生成,且通过使用同一个类或其他类中的委托与事件处理程序关联。 包含事件的类用于发布事件。这被称为 发布器(publisher) 类。其他接受该事件的类 被称为 订阅器(subscriber) 类。事件使用 发布-订阅(publisher-subscriber) 模型。

    发布器(publisher) 是一个包含事件和委托定义的对象。事件和委托之间的联系也定义 在这个对象中。发布器(publisher)类的对象调用这个事件,并通知其他的对象。

    订阅器(subscriber) 是一个接受事件并提供事件处理程序的对象。在发布器(publisher) 类中的委托调用订阅器(subscriber)类中的方法(事件处理程序)。

    简单来说就是事件可以为任何一种委托类型提供一种发布/订阅机制。用户可以订阅这 个事件,当发布者触发事件后,所有的订阅者都会收到通知。关键是发布者不知道订阅 者是谁,有多少个订阅者。这样的好处是各个模块可以专心做自己的事,不需要过问其 他模块的事情。

    声明事件步骤

    在类的内部声明事件,首先必须声明该事件的委托类型。例如:

    public delegate void PrintHandler();

    其次,使用 event 关键字声明事件本身:

    public event PrintHandler printTest;

    上面的代码定义了一个名为 PrintHandler的委托和一个名为 PrintTest 的事件,该事件在生成的时候会调用委托。

    然后调用事件,但是只能在声明事件的类中调用事件

    1. If(printTest!=null)
    2. printTest();

    或者

    printTest?.Invoke();

    这个代码就是判断printTest是否为空,不为空就调用printTest()方法,为空就不执行

    最后注册事件,这里声明事件的类为Sample类

    Sample.printTest+=实例方法/静态方法

    取消订阅的话用-=即可

    下面用一段代码演示:

    1. using System;
    2. namespace ConsoleApp1
    3. {
    4. //发布器类
    5. public class Sample
    6. {
    7. //声明委托
    8. public delegate void OrderEventHandler(int x);
    9. //声明事件
    10. public event OrderEventHandler order;
    11. //调用事件
    12. protected virtual void OnCall()
    13. {
    14. order?.Invoke(99);
    15. }
    16. public void Start()
    17. {
    18. OnCall();
    19. }
    20. }
    21. //订阅器类-1
    22. public class SubscribEvent1
    23. {
    24. public void Print(int x)
    25. {
    26. Console.WriteLine("订阅器1,打印数字:"+x);
    27. }
    28. }
    29. //订阅器类-2
    30. public class SubscribEvent2
    31. {
    32. public void Print(int x)
    33. {
    34. Console.WriteLine("订阅器2,打印数字:"+x);
    35. }
    36. }
    37. class Program
    38. {
    39. static void Main(string[] args)
    40. {
    41. //实例化对象-订阅器类
    42. SubscribEvent1 se1 = new SubscribEvent1();
    43. SubscribEvent2 se2 = new SubscribEvent2();
    44. //实例化对象-发布器类
    45. Sample sample = new Sample();
    46. //订阅
    47. sample.order += se1.Print;
    48. sample.order += se2.Print;
    49. //调用事件
    50. sample.Start();
    51. Console.ReadLine();
    52. }
    53. }
    54. }

    输出结果:

    1. 订阅器1,打印数字:99
    2. 订阅器2,打印数字:99

    上面我们用发布器类的start函数来调用Oncall函数引发一个事件。通常要引发事件, 应该使名称定义受保护的虚拟方法,protected和virtual使派生类能够覆盖引发事件的 逻辑,但是派生类要始终调用这个受保护的方法,以确保注册的委托接收事件

    我们+=来订阅事件,这里订阅了两个方法,当调用事件时这两个方法都会调用

    内置 EventHandler 委托

    系统内置了两个常用的委托类型 EventHandler EventHandler 。通常, 任何事件都应包括两个参数:事件源和事件数据。EventHandler 主要用于不包含事件数 据;对包含事件数据的使用 EventHandler

    如有错漏之处,敬请指正!

  • 相关阅读:
    PMP项目管理实战 | 高效协作的团队从哪里来?
    jQuery的事件
    2022 极术通讯-Arm体系结构的同步概述和案例研究
    websocket服务部署在内网,app无法访问
    SSM宾馆客房管理系统开发mysql数据库web结构java编程计算机网页源码eclipse项目
    昆泰芯微KTH78系列介绍大全
    el-table相同的值合并单元格+多级表头
    难得五年来第一次暑假没有出海,即使最终没有逃过8月份的CPT外业
    某60区块链安全之Call函数簇滥用实战一学习记录
    Spring之bean的细节(创建方式、作用范围、生命周期)
  • 原文地址:https://blog.csdn.net/qq_52905520/article/details/126285171