C#事件event

news2024/11/19 3:44:44

事件模型的5个组成部分
事件拥有者(event source)(类对象)(有些书将其称为事件发布者)
事件成员(event)(事件拥有者的成员)(事件成员就是事件本身,事件不会主动发生,其只会在事件拥有者的内部逻辑的触发下发生。)
事件响应者(event subscriber)(类对象)(有些书将其称为事件订阅者)
事件处理器(event handler)(事件的响应者的成员)(根据拿到的事件参数/信息对事件进行处理)
事件订阅(委托类型)

举个栗子:妈妈喊儿子回家吃饭,儿子听到立马跑回家。

在上面这个例子中,事件拥有者是妈妈(Mother),事件成员是喊(Say),事件响应者是儿子(Son),事件处理是跑步回家(Gohome)

接下来我们尝试去写这个过程

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp5event
{
    //事件拥有者(event source)(类对象)(有些书将其称为事件发布者)
    //事件成员(event)(事件拥有者的成员)(事件成员就是事件本身,事件不会主动发生,其只会在事件拥有者的内部逻辑的触发下发生。)
    //事件响应者(event subscriber)(类对象)(有些书将其称为事件订阅者)
    //事件处理器(event handler)(事件的响应者的成员)(根据拿到的事件参数/信息对事件进行处理)
    //事件订阅(委托类型 delegate)
    //举个栗子1:“裁判员开枪,运动员开始跑步。”
    //1.1事件拥有者是裁判员,
    //1.2事件成员是开枪,
    //1.3事件响应者是运动员,
    //1.4事件处理是开始跑步。
    //举个栗子2:这是WinForm编程中常用的一种方式,比如在一个窗体中,存在一个文本框和按钮,现在要通过点击按钮让文本框上显示出文字“Hello World”。
    //2.1发生的事件是:鼠标点击;
    //2.2事件拥有者是:按钮(Button),鼠标点击的是它,它是窗体对象的一个字段成员;
    //2.3事件响应者是窗体对象;
    //2.4事件处理是:窗体对象让自己的字段成员文本框(TextBox)显示出文字“Hello World”。

    //从发生到响应的5个动作:①事件拥有者拥有一个事件→②事件响应者订阅了这个事件→③事件拥有者触发了事件→④事件响应者会被依次通知到(按照订阅的顺序)→⑤事件响应者根据拿到的事件参数对事件进行处理

    //下面的示例是:你妈妈喊“回家吃饭”,你(儿子)跑步回家。
    //事件拥有者是妈妈,
    //事件成员是喊话,
    //事件响应者是儿子,
    //事件处理是跑步回家。

    //在声明事件之前,需要先声明一个委托类型来作为约束,即事件订阅,其约束了事件(喊话)能够发送什么事件参数给事件响应者(儿子),以及当事件响应者(儿子)的事件处理器(跑步回家)符合规定时(即符合委托类型指定的签名和返回值类型),事件订阅要将其保存起来(即委托字段引用方法)。根据命名规范,该委托应该命名为“事件名+EventHandler”。
    //可以将事件标记为public、private、protected、internal、protected internal 或 private protected。 这些访问修饰符定义该类的用户访问该事件的方式。 

    internal class Program
    {
        static void Main(string[] args)
        {
            Mother mother = new Mother();//事件的拥有者
            Son son = new Son();//事件的相应者
            mother.Say += son.Gohome; //事件Say,事件处理器gohome,事件订阅+= 也就是只要妈妈说话了,儿子就时时刻刻接收妈妈说的话
            mother.SayingProcess(); //触发事件,模拟妈妈喊儿子回家过程
            Console.ReadKey();
        }
    }


    //用于传递事件参数(事件信息)的类,该例子中主要用于将妈妈的话传递给儿子
    public class SayEventArgs : EventArgs
    {
        public String sentence { get; set; } //说了什么话
    }

    //声明委托类型(事件订阅)
    //第1个参数为事件拥有者(妈妈),第2个参数是用来存储喊儿子回家的相关信息(事件参数) 
    public delegate void SayEventHandler(Mother mother, SayEventArgs e);

    //妈妈类:事件拥有者
    public class Mother
    {
        //根据前面声明的委托类型来创建一个委托类型字段,用来触发事件处理器(儿子回家)
        private SayEventHandler sayEventHandler;

        //声明事件:
        //event为事件关键字,SayEventHandler表示用此委托来约束该事件
        public event SayEventHandler Say
        {
            //添加事件处理器
            add
            {
                sayEventHandler += value;
            }
            //删除事件处理器
            remove
            {
                sayEventHandler -= value;
            }
        }
        //下面的Say就相当于上面的Say(事件和儿子的动作进行绑定)和SayEventArgs(事件传输参数,用于将妈妈的话传给儿子)
        //public void Say(string sentence)
        //{
        //    Console.WriteLine("妈妈说:"+sentence);
        //}
        //模拟妈妈喊儿子的过程:
        public void SayingProcess()
        {
            Console.WriteLine("输入回车后开始模拟:妈妈做好饭喊儿子回家");
            Console.ReadLine();
            Console.WriteLine("妈妈已经做好饭了");
            Thread.Sleep(1000);
            Console.WriteLine("妈妈走向窗户边");
            Thread.Sleep(1000);
            Console.WriteLine("妈妈准备喊话");
            Thread.Sleep(1000);
            //触发事件:
            if (sayEventHandler != null) //若不存在任何事件处理器则无法触发事件
            {
                //准备好事件参数(即准备好妈妈想说的话)
                SayEventArgs e = new SayEventArgs();
                e.sentence = "儿子回家吃饭了";
                Console.WriteLine("妈妈说:“"+e.sentence+"”");
                Thread.Sleep(1000);
                //调用事件处理器(就是)
                sayEventHandler(this, e);
                e.sentence = "儿子买点盐去,家里没有盐了";
                Console.WriteLine("妈妈说:“" + e.sentence + "”");
                Thread.Sleep(1000);
                sayEventHandler(this, e);
            }
        }
    }
    //儿子类:事件响应者
    public class Son
    {
        //想儿子要回家的话,首先得有妈妈约束(所以第一个参数是事件的拥有者),其次是妈妈做了什么(喊吃饭,所以第二个参数是事件)才能让儿子回家
        //此处的参数必须与SayEventHandler一样
        public void Gohome(Mother mother, SayEventArgs e)
        {
            Thread.Sleep(1000);
            Console.WriteLine("儿子接收到妈妈的话:"+e.sentence);
            Thread.Sleep(1000);
            if (e.sentence.Contains("回家"))
            {
                Console.WriteLine("儿子说:“好的,妈妈,我马上回家吃饭”");
            }
            else {
                Console.WriteLine("儿子说:“妈妈,自己去买呗,我还想在外面玩会”");
            } 
        }
    }

}

运行结果如下 

参考文献

event - C# 参考 - C# | Microsoft Learn

C# 事件(event)_c# event_熊思宇的博客-CSDN博客

C#中的事件(event)_c# event_香芋派丶的博客-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/983733.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023年03月 C/C++(八级)真题解析#中国电子学会#全国青少年软件编程等级考试

C/C编程&#xff08;1~8级&#xff09;全部真题・点这里 第1题&#xff1a;最短路径问题 平面上有n个点&#xff08;n<100&#xff09;&#xff0c;每个点的坐标均在-10000~10000之间。其中的一些点之间有连线。 若有连线&#xff0c;则表示可从一个点到达另一个点&#xff…

C++——STL容器【map和set】

文档&#xff1a;map、set 文章目录 &#x1f36f;1. 关联式容器&#x1fad6;2. set&#x1f37c;1. 模板参数&#x1f37c;2. 构造函数&#x1f37c;3. 修改&#x1f37c;4.操作&#x1f95b;find&#x1f95b;count&#x1f95b;lower_bound & upper_bound & equal_…

Increment Selection 插件

Increment Selection 插件实现递增 初次使用 按下快捷键 Alt Shift 鼠标左键向下拖拽 向下拖拽之后&#xff0c;在输入一个数字&#xff0c;比如我这里输入了一个数字1 然后按下快捷键 Ctrl Shift ← 进行选中数字 然后按下快捷键 Ctrl Alt i 建自动递增。 然后鼠标随…

网络是如何进行通信

网络是如何进行通信的 简介 在现代社会中&#xff0c;网络已经成为我们生活中不可或缺的一部分。从上网搜索信息、在线购物到远程工作和社交媒体&#xff0c;我们几乎无时无刻不与网络保持着联系。但是&#xff0c;网络究竟是个什么玩意&#xff0c;它是如何工作的呢&#xf…

MinIO集群模式信息泄露漏洞(CVE-2023-28432)

前言&#xff1a;MinIO是一个用Golang开发的基于Apache License v2.0开源协议的对象存储服务。虽然轻量&#xff0c;却拥有着不错的性能。它兼容亚马逊S3云存储服务接口&#xff0c;非常适合于存储大容量非结构化的数据。该漏洞会在前台泄露用户的账户和密码。 0x00 环境配置 …

数字信封技术概论

数字信封技术是一种通过加密手段实现信息保密性和验证的技术&#xff0c;它在保护敏感信息传输过程中得到了广泛应用。本文将详细介绍数字信封技术的原理、实现和应用场景。 一、数字信封技术的原理 数字信封技术是一种将对称密钥通过非对称加密手段分发的方法。在数字信封中…

《C++设计模式》——行为型

前言 行为型模式是对在不同的对象之间划分责任和算法的抽象化。行为型模式不仅仅关注类和对象的结构&#xff0c;而且重点关注它们之间的相互作用。 Interpreter(解释器) Template Method(模板方法) Chain of Responsibility(责任链) Command(命令) Iterator(迭代器) Me…

海康NVR(Network Video Recorder)启用SSH过程摸索

文章目录 海康NVR具备的特点启用SSH模式优劣比较启用SSH模式的优势启用SSH模式的坏处 Hik NVR启用SSH功能1&#xff0c;Web登录NVR2&#xff0c;SSH登录NVR SSH shell模式特点SSH shell模式指令作用1&#xff0c;简要帮助“help”可以列出常用的shell指令部分可用shell指令输出…

实现一台电脑登录多个微信账号/一个微信账号在多台电脑登录

一、一台电脑登录多个微信账号 在电脑桌面建立一个txt文档文件。 输入内容: echo off start /d"C:\Program Files\Tencent\WeChat\" WeChat.exe start /d"C:\Program Files\Tencent\WeChat\" WeChat.exe exit 如下图&#xff0c;/d"引号内容写微信安…

KT142C-sop16语音芯片ic的串口指令详细说明_默认9600指令可设

3.1 通讯格式 支持异步串口通讯模式,通过串口接受上位机发送的命令 通讯标准:9600 bps --- 可以发送指令修改&#xff0c;并且记忆&#xff0c;详见3.4.5 数据位 :8 停止位 :1 校验位 :none 流控制 :none 格式&#xff1a;$S VER Len CMD Feedback para1 …

简单便捷的行为验证码,让登录更轻松

前言 在当今数字化的世界里&#xff0c;登录账户已成为我们日常生活中不可或缺的一部分。然而&#xff0c;传统的输入验证码方式却常常给用户带来不必要的繁琐和麻烦。为了解决这一问题&#xff0c;简单便捷的行为验证码应运而生&#xff0c;让登录变得更加轻松。 行为验证码…

TuyaOS Sensor Hub组件介绍

文章目录 Sensor Hub 设计思想分层设计Sensor Hub 层(tdl)Sensor Driver 层(tdd) 传感数据元素类型抽象传感器采集策略 Sensor Hub 对上数据与接口数据结构1. 数据读取的触发模式2. 元素型数据订阅规则3. 数据就绪通知回调4. 传感设备信息 应用接口1. 创建传感器实例2. 启动传感…

vue3路由跳转params传参接收不到

import { useRouter } from "vue-router";const router useRouter(); // 提现记录 const withdrawalClick (item) > {router.push({ name: "Devwithdrawal", params: { name: 123 } }); };//跳转页面接收参数 import { useRoute } from "vue-rou…

指针和字符数组笔试题及其解析(第二组)

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 前言&#xff1a; 数组名在寻常情况下表示首元素地址&#xff0c;但有两种情况例外&#xff1a; 1.sizeof(数组名)&#xff0c;这里的数组名表示整个数组&#xff0c;计算的是整个数组的大小 2.&数组名&#xff0c;这里的…

OLED透明屏模块:引领未来显示技术的突破

OLED透明屏模块作为一项引领未来显示技术的突破&#xff0c;以其独特的特点和卓越的画质在市场上引起了广泛关注。 根据行业报告&#xff0c;预计到2025年&#xff0c;OLED透明屏模块将占据智能手机市场的20%份额&#xff0c;并在汽车导航系统市场中占据30%以上份额。 那么&am…

TD3算法

TD3算法 全称Twin Delayed DDPG&#xff0c;是对DDPG算法的继承、发展和改进&#xff0c;论文 改进如下&#xff1a; T w i n \mathcal{T}win Twin&#xff1a;使用了两个critic来评估actor的动作价值&#xff0c;对应两个critic target&#xff0c;一个actor target&#xff0…

[漏洞复现] metinfo_6.0.0_file-read(任意文件读取)

文章目录 漏洞描述漏洞等级影响版本漏洞复现基础环境漏洞点第一次测试第二次测试第三次测试第四次测试深度利用EXP编写EXP使用案例漏洞挖掘指纹信息修复建议 本次漏洞复现仅供学习使用&#xff0c;如若非法他用&#xff0c;与平台和本文作者无关&#xff0c;需自行负责&#xf…

Solidity 小白教程:10. 控制流,用 solidity 实现插入排序

Solidity 小白教程&#xff1a;10. 控制流&#xff0c;用 solidity 实现插入排序 这一讲&#xff0c;我们将介绍solidity中的控制流&#xff0c;然后讲如何用solidity实现插入排序&#xff08;InsertionSort&#xff09;&#xff0c;一个看起来简单&#xff0c;但实际上很容易…

系统架构设计师(第二版)学习笔记----计算机系统基础

【原文链接】系统架构设计师&#xff08;第二版&#xff09;学习笔记----计算机系统基础 文章目录 一、计算机硬件1.1 计算机硬件的组成1.2 处理器指令集1.3 处理器层次1.4 总线分类1.5 接口的种类 二、计算机操作系统2.1 计算机软件分类2.2 操作系统的作用2.3 操作系统的特征2…

【FusionInsight 迁移】HBase从C50迁移到6.5.1(01)迁移概述

【FusionInsight 迁移】HBase从C50迁移到6.5.1&#xff08;01&#xff09;迁移概述 HBase从C50迁移到6.5.1&#xff08;01&#xff09;迁移概述迁移范围迁移前的准备HDFS文件检查确认HBase迁移目录确保数据落盘停止老集群HBase服务停止新集群HBase服务 HBase从C50迁移到6.5.1&a…