C# 事件详解

C# 事件

      • 一、事件
      • 二、事件的应用
      • 三、事件的自定义声明

一、事件

  1. 定义:“a thing that happens, especially something important” / “能够发生的什么事情”
  2. 角色:使对象或类具备通知能力的成员
  3. 使用:用于对象或类间的动作协调与信息传递
  4. 事件的功能=通知+可选的事件参数
  5. 原理:事件模型中的两个“5”
    • “发生->响应”中的5个部分:事件的拥有者,事件的响应者,事件,事件处理器,事件订阅
    • “发生->响应”中的5个动作:
      (1)我有一个事件
      (2)一个人或者一群人关心(即“订阅”)我这个事件
      (3)我的这个事件发生了
      (4)关心这个事件的人会被依次通知到
      (5)被通知的人根据拿到的信息(即“事件数据”、“事件参数”、“通知”)对事件进行响应(即“事件处理”)
    1. 事件的本质是委托字段的一个包装器。

二、事件的应用

事件模型的五个组成部分:

  1. 事件的拥有者(event source,对象)
  2. 事件(event,成员)
  3. 事件的响应者(event subscriber,对象)
  4. 事件处理器(event handler,成员)——本质上是一个回调方法
  5. 事件订阅——把事件处理器和事件关联在一起,本质上是一种以委托类型为基础的“约定”
using System.Timers;
namespace EventExample
{class Program{static void Main(string[] args){System.Timers.Timer timer = new System.Timers.Timer();//1.事件的拥有者timer.Interval = 1000;Boy boy = new Boy();//3.事件的响应者//2.事件:Elapsedtimer.Elapsed += new ElapsedEventHandler( boy.Action);//5.订阅事件timer.Start();Console.ReadLine();           }}class Boy{//4.事件处理器internal void Action(object? sender, ElapsedEventArgs e){Console.WriteLine("Jump");}}}
  • 第一种组合模式:事件的拥有者和事件的响应者是不同的对象
    在这里插入图片描述
namespace EventExample2
{internal static class Program{static void Main(){Form form = new Form();Controller controller = new Controller(form);form.ShowDialog();}}class Controller {private Form form;public Controller(Form form ){if (form != null) {this.form = form;this.form.Click += this.FormClicked;}}private void FormClicked(object sender, EventArgs e){this.form.Text = DateTime.Now.ToString();}}
}
  • 第二种组合模式:事件的拥有者和时间的响应者是同一个对象
    在这里插入图片描述
namespace EventExample3
{internal static class Program{static void Main(){MyForm form = new MyForm();form.Click += form.FormClicked;form.ShowDialog();}}class MyForm : Form{internal void FormClicked(object sender, EventArgs e){this.Text = DateTime.Now.ToString();}}}
  • 第三张组合模式:事件的拥有者是事件的响应者的一个字段成员

    在这里插入图片描述

namespace EventExample4
{internal static class Program{static void Main(){MyForm form = new MyForm();           form.ShowDialog();}}class MyForm : Form{private TextBox textBox;private Button button;public MyForm(){this.textBox = new TextBox();this.button = new Button();this.button.Text = "Say Hello!";this.button.Top = 30;this.button.Click += this.ButtonClicked;this.Controls.Add(this.textBox);this.Controls.Add(this.button);}private void ButtonClicked(object sender, EventArgs e){this.textBox.Text = "Hello world!";}}}

在这里插入图片描述

在这里插入图片描述

订阅的几种写法

 //方法一:直接挂载处理器this.button1.Click += Button1_Click;//方法二:使用委托this.button1.Click += new EventHandler(this.Button1_Click);//方法三:使用委托this.button1.Click += delegate (object? sender, EventArgs e){this.Text = DateTime.Now.ToString();};//简写this.button1.Click +=  (sender, e)=>{this.Text = DateTime.Now.ToString();};

三、事件的自定义声明

完整声明

  • 规定输出类型和输入参数
  • 根据规定声明委托
  • 在事件拥有者类中声明委托字段
  • 根据委托声明事件
  • 订阅事件(把委托和响应事件绑定)
  • 调用委托
    (相对于间接调用了响应事件)
namespace EventExample
{class Program{public static void Main(string[] args){Customer customer = new Customer();Waiter waiter = new Waiter();customer.Order += waiter.Action;customer.Action();customer.PayTheBill();}}public class OrderEventArgs : EventArgs{public string DishName { get; set; }public string Size { get; set; }}//声明委托public delegate void OrderEventHandler(Customer customer, OrderEventArgs e);public class Customer{//声明委托字段private OrderEventHandler? orderEventHandlerOrder;//声明事件public event OrderEventHandler Order{add{this.orderEventHandlerOrder += value;}remove{this.orderEventHandlerOrder -= value;}}public double Bill { get; set; }public void PayTheBill(){Console.WriteLine("I will pay ${0}.", this.Bill);}public void WalkIn(){Console.WriteLine("Walk into the restaurant.");}public void SitDown(){Console.WriteLine("Sit down.");}public void Think(){for (int i = 0; i < 5; i++){Console.WriteLine("Let me think...");Thread.Sleep(1000);}if (this.orderEventHandlerOrder != null){OrderEventArgs e = new OrderEventArgs();e.DishName = "辣椒擂皮蛋";e.Size = "large";this.orderEventHandlerOrder.Invoke(this, e);}}public void Action(){Console.ReadLine();this.WalkIn();this.SitDown();this.Think();}}public class Waiter{internal void Action(Customer customer, OrderEventArgs e){Console.WriteLine("I will serve you the dish -{0}.", e.DishName);double price = 10;switch (e.Size){case "small":price = price * 0.5;break;case "large":price = price * 1.5;break;}customer.Bill += price;}}}

在这里插入图片描述

简略声明

 public class Customer{//简略声明事件public event OrderEventHandler Order;....public void Think(){...if (this.Order != null){...this.Order.Invoke(this, e);}}public void Action(){...this.Think();}}

使用EventHandler声明事件

public delegate void EventHandler(object? sender, EventArgs e);

 public class Customer{//使用EventHandler 声明事件public event EventHandler Order;...}public class Waiter{internal void Action(Object sender, EventArgs e){//强制转换Customer? customer = sender as Customer;OrderEventArgs? orderInfo = e as OrderEventArgs;...}}

注意:

  • 一般事件命名为××EventHandler
  • 事件参数命名为××EventArgs
  • 触发事件命名为On××,访问级别为protected
    修改后的代码
 public class Customer{...this.OnOrder("辣椒擂皮蛋", "large");      }private void OnOrder(string dishName, string size) {if (this.Order != null){OrderEventArgs e = new OrderEventArgs();e.DishName = dishName;e.Size = size;this.Order.Invoke(this, e);}}...}

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

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

相关文章

青少年编程与数学 01-011 系统软件简介 24 Kubernetes 容器编排系统

青少年编程与数学 01-011 系统软件简介 24 Kubernetes 容器编排系统 一、历史沿革&#xff08;一&#xff09;起源1. Google 内部起源 &#xff08;二&#xff09;开源后的关键事件&#xff08;三&#xff09;社区治理 二、技术架构&#xff08;一&#xff09;分层设计哲学&…

[C++] : 谈谈IO流

C IO流 引言 谈到IO流&#xff0c;有些读者可能脑海中第一个想到的C程序员的最基础的std::cout &#xff0c; std::cin两个类的使用&#xff0c;对的&#xff0c;这个就是一个典型的IO流&#xff0c;所以逆天我们这篇文章会基于C IO流的原理和各种应用场景进行深入的解读。 C…

Kafka 3.0零拷贝技术全链路源码深度剖析:从发送端到日志存储的极致优化

在分布式消息系统领域&#xff0c;Kafka凭借高吞吐、低延迟的特性成为行业首选。而零拷贝技术作为Kafka性能优化的核心引擎&#xff0c;贯穿于消息从生产者发送、Broker接收存储到消费者读取的全生命周期。本文基于Kafka 3.0版本&#xff0c;深入源码层面&#xff0c;对零拷贝技…

利益驱动机制下开源AI智能名片链动2+1模式与S2B2C商城小程序的商业协同研究

摘要&#xff1a;在数字经济时代&#xff0c;利益驱动作为用户行为激励的核心逻辑&#xff0c;正通过技术创新实现模式升级。本文基于“利益驱动”理论框架&#xff0c;结合“开源AI智能名片链动21模式S2B2C商城小程序”的技术架构&#xff0c;系统分析物质利益&#xff08;返现…

pytest的前置后置条件

1. setUp()和tearDown() setup()函数主要是进行测试前的初始化工作&#xff0c;比如&#xff1a;在接口测试前面做一些前置的参数赋值&#xff0c;数据库操作等等。 teardown()函数是测试后的清除工作&#xff0c;比如&#xff1a;参数还原或销毁&#xff0c;数据库的还原恢复…

Python 自动化运维与DevOps实践

https://www.python.org/static/community_logos/python-logo-master-v3-TM.png 基础设施即代码(IaC) 使用Fabric执行远程命令 python 复制 下载 from fabric import Connectiondef deploy_app():# 连接到远程服务器with Connection(web-server.example.com, userdeploy,…

css3 文本效果(text-shadow、text-overflow、word-wrap、word-break)文本阴影、文本换行、文本溢出并隐藏显示省略号

1. 文本阴影&#xff08;text-shadow&#xff09; 1.1 基本语法 text-shadow: h-shadow v-shadow blur-radius color;参数说明&#xff1a; h-shadow&#xff1a;必需。水平阴影的位置。允许负值。 正值&#xff1a;向右偏移负值&#xff1a;向左偏移 v-shadow&#xff1a;必…

在Kibana上新增Elasticsearch生命周期管理

技术文章大纲&#xff1a;在Kibana上新增Elasticsearch生命周期管理 引言 Elasticsearch索引生命周期管理&#xff08;ILM&#xff09;是管理索引从创建到删除全周期的核心工具。通过Kibana界面配置ILM策略&#xff0c;可以自动化处理索引的滚动、收缩、冻结和删除等操作&…

从零开始构建Python聊天机器人:整合NLP与深度学习

引言 在人工智能快速发展的今天&#xff0c;聊天机器人已经成为企业与用户交互的重要工具。从客户服务到信息查询&#xff0c;从个人助手到教育辅助&#xff0c;聊天机器人的应用场景越来越广泛。构建一个智能、高效的聊天机器人不仅需要了解自然语言处理&#xff08;NLP&…

光谱相机的多模态成像技术详解

一、技术架构与工作原理‌ 多模态成像通过‌同步集成多种光谱成像技术‌&#xff08;如高光谱多光谱热成像&#xff09;&#xff0c;构建“空间-光谱-时间”三维数据立方体&#xff0c;实现物质成分与动态过程的协同感知。核心架构包含&#xff1a; ‌分光系统‌ ‌液晶可调…

Spring Boot多数据源切换:三种实现方式详解与实战

在复杂业务系统中&#xff0c;多数据源切换已成为必备技能。本文将深入剖析三种主流实现方案&#xff0c;带你从入门到精通&#xff01; 一、多数据源应用场景 读写分离&#xff1a;主库负责写操作&#xff0c;从库处理读请求 多租户系统&#xff1a;不同租户使用独立数据库 …

Kafka性能压测报告撰写

在大数据生态体系中&#xff0c;Kafka以其卓越的高吞吐、低延迟特性&#xff0c;成为消息队列领域的中流砥柱。然而&#xff0c;随着业务规模不断扩张&#xff0c;数据流量日益激增&#xff0c;Kafka的性能表现直接关乎业务系统的稳定运行与效率提升。通过科学严谨的性能压测&a…

使用DevEco Testing快速创建HarmonyOS5单元测试

1.测试环境准备 确保已安装DevEco Studio 5.0在module的build.gradle添加依赖&#xff1a; dependencies {testImplementation org.junit.jupiter:junit-jupiter:5.8.2ohosTestImplementation com.huawei.ohos.testkit:runner:1.0.0.200 }2.创建测试类&#xff08;示例测试计…

开源物联网(IoT)平台对比

一些 开源物联网&#xff08;IoT&#xff09;平台&#xff0c;它们广泛应用于设备管理、数据采集、远程监控和边缘计算等场景&#xff1a; &#x1f31f; 主流开源物联网平台 平台描述技术栈许可证ThingsBoard功能丰富&#xff0c;支持设备管理、遥测数据收集、规则引擎、告警…

插值与模板字符串

背景。表单渲染需要获取对象中属性进行赋值操作。 插值错误使用。以下方举例。其中的placeholder不能被正确渲染。因为Vue 不会解析 {{ }} 在属性中的内容&#xff1b;如果这样写编译会出问题&#xff0c;而且比较难找出是哪的问题 模板字符串。正确做法时使用。模板字符串用…

Luckfox Pico Pi RV1106学习<4>:RV1106的帧率问题

Luckfox Pico Pi RV1106学习&#xff1c;4&#xff1e;&#xff1a;RV1106的帧率问题 1. 背景2. 问题 1. 背景 接上篇。我在应用中创建3个线程&#xff1a; CAM线程&#xff0c;使用V4L2驱动&#xff0c;从 /dev/video11 获取图像。ENC线程&#xff0c;使用硬件编码器&#x…

内测分发平台应用的异地容灾和负载均衡处理和实现思路?

在软件开发过程中&#xff0c;内测分发平台扮演着至关重要的角色。它不仅帮助开发者将应用程序传播给内部测试人员&#xff0c;还负责收集反馈、跟踪错误并改进产品。然而&#xff0c;为了确保一个平稳、连贯的内测过程&#xff0c;对内测分发平台实施异地容灾和负载均衡机制是…

国内用户如何高效升级npm:使用阿里云镜像加速指南

文章目录 引言为什么需要升级npm?环境检查使用阿里云镜像安装nvm配置阿里云镜像加速npm使用nvm安装最新Node.js验证安装结果升级npm到最新版本解决常见问题1. 权限问题2. 镜像源验证3. 项目创建失败创建测试项目总结引言 作为前端开发者,npm(Node Package Manager)是我们日…

LeetCode--34.在排序数组中查找元素的第一个和最后一个位置

解题思路&#xff1a; 1.获取信息&#xff1a; 给定一个非递减顺序的整数数组&#xff0c;要求找出给定元素在该数组中从左往右第一次出现的位置和最后一个出现的位置&#xff0c;即&#xff1a;最右边的位置和最左边的位置 如果不存在该元素&#xff0c;则返回{ -1 , -1 } 限制…

低秩分解的本质是通过基矩阵和系数矩阵的线性组合,以最小的存储和计算代价近似表示复杂矩阵

低秩分解的本质是通过基矩阵和系数矩阵的线性组合&#xff0c;以最小的存储和计算代价近似表示复杂矩阵 flyfish 一、最基础起点&#xff1a;数字与数组 数字与标量&#xff08;Scalar&#xff09; 单独的数&#xff0c;如 1 , 2.5 , − 3 1, 2.5, -3 1,2.5,−3&#xff0c;…