• C# 事件


    零、广播者和订阅者

    使用委托的时候通常会出现两个角色,分别是广播者和订阅者。广播者包含委托字段,通过调用委托来决定何时进行广播。订阅者是方法目标的接收者,订阅者决定什么时候开始监听和结束监听,开始监听在委托上使用+=,结束监听在委托上使用-=。.NET环境下,一个订阅之不知道其他订阅者的存在,同时也不会干扰其他订阅者。

    一、事件

    事件(Event) 是一种结构,将广播/订阅模式正式化为语言特性,并且只暴漏所需的委托特性的部分子集。事件存在的主要目的是防止订阅者相互干扰。

    1. 声明事件
      声明事件只需在委托前面加上 event 关键字即可。例子如下:
    public delegate void StudentHandler(string name);
    
    public class School
    {
        public event StudentHandler student;
        // more code
        // ......
    }
    

    这里我们来解释一下上面的代码,我们在代码外侧定义了一个委托 StudentHandler ,并且在类 School 中定义了一个事件。在这段代码中 School 类中的所有代码可以把 student 完全当作委托来使用。但是在 School 类外部只能对 student 这个时间执行 +=和-=操作。

    1. 事件模式
      .NET中有一个预定义框架类 System.EventArgs ,其中只有静态属性 Empty,所有的传递信息的类都必须继承自这个预定义框架类。 我们来通过一个例子来看一下:
    public class SchoolEventArgs:System.EventArgs
    {
        public readonly string Name;
    
        public SchoolEventArgs(string name)
        {
            Name = name;
        }
    }
    

    上面代码中的只读字段 Name 是我们要传递的信息,一般情况下要传递的信息会使用 属性 或者 只读字段

    当我们编写完传递信息的类之后,就需要为事件定义委托了,为事件定义委托有如下几个硬性要求:

    • 返回类型必须是 void ;
    • 必须接受两个参数,第一个参数是 object (事件的广播者) ,第二个参数是 EventArgs 的子类 (要传递的信息);
    • 名称必须以 EventHandler 结尾

    下面我们就行定义事件,定义事件就简单了,例子如下:

    public delegate void StudentHandler(string name);
    
    public class School
    {
        public event StudentHandler student;
    }
    

    定义完事件之后还需要定义触发事件的方法,触发时间的方法也有如下两点要求:

    • 方法必须以 protected 修饰;
    • 方法名命名必须是 On事件名* 的格式,并且接受一个 EventArgs 参数。

    我们来看一下代码:

    public delegate void StudentEventHandler(object source, SchoolEventArgs e);
    public class School
    {
        string name;
        public event StudentEventHandler studentEventHandler;
    
        protected virtual void OnStudentHandlerEventHandler(SchoolEventArgs e)
        {
            studentEventHandler?.Invoke(this,e);
        }
    
        public string Name
        {
            get { return name; }
            set
            {
                name = value;
                OnStudentHandlerEventHandler(new SchoolEventArgs(name));
            }
        }
    }
    

    到现在为止,我们该定义的都定义完了,现在我们来看一下怎么调用:

    class Program
    {
        static void Main(string[] args)
        {
            School school = new School();
            school.studentEventHandler += School_studentEventHandler;
            school.Name = "李四";
            Console.Read();
        }
    
        private static void School_studentEventHandler(object source, SchoolEventArgs e)
        {
            Console.WriteLine(e.Name);
        }
    }
    

    执行上述代码,得到如下结果:

    mphD8U.png

  • 相关阅读:
    Idea导出jar包运行报错:找不到主清单属性解决方法
    Java开发桌面程序学习(一)——JavaFx+Jfoenix初始以及搭建
    JavaFx出现错误Caused by: java.lang.NullPointerException: Location is required的解决方法
    IDEA maven设置配置
    oracle学习笔记(十九) 子程序——存储过程
    ASP.NET Core 指定环境发布(hosting environment)
    解决Visual Studio 2017隐藏“高级保存选项”命令
    【亲测可用,亦可配置同一平台的不同账号,例如阿里云的两个不同账号】Windows下Git多账号配置,同一电脑多个ssh-key的管理
    Xshell5 评估过期,需要采购,不能使用
    linux上mongodb的安装与卸载
  • 原文地址:https://www.cnblogs.com/gangzhucoll/p/12778176.html
Copyright © 2020-2023  润新知