当前位置: 首页 > news >正文

C#的委托delegate与事件event

在C#中,delegate(委托)和 event(事件)是两个非常重要的概念,它们主要用于实现回调机制和事件驱动编程。下面详细介绍它们的原理和使用场景。

1. Delegate(委托)
1.1 委托的原理
委托是一种类型,它定义了方法的签名(即方法的参数类型和返回类型)。

委托可以看作是一个函数指针,它允许将方法作为参数传递、存储和调用。

委托是类型安全的,编译器会检查委托和方法签名是否匹配。

委托可以绑定到一个或多个方法(多播委托)。

1.2 委托的声明与使用
声明委托

// 定义一个委托类型,它指向一个没有返回值且接受一个string参数的方法
public delegate void MyDelegate(string message);
使用委托
public class Program
{// 定义一个符合委托签名的方法public static void DisplayMessage(string message){Console.WriteLine("Message: " + message);}public static void Main(string[] args){// 创建委托实例并绑定方法MyDelegate myDelegate = new MyDelegate(DisplayMessage);// 调用委托myDelegate("Hello, Delegate!");}
}
多播委托

委托可以绑定多个方法,调用时会依次执行这些方法。

public class Program
{public static void DisplayMessage1(string message){Console.WriteLine("Message 1: " + message);}public static void DisplayMessage2(string message){Console.WriteLine("Message 2: " + message);}public static void Main(string[] args){MyDelegate myDelegate = DisplayMessage1;myDelegate += DisplayMessage2; // 绑定第二个方法myDelegate("Hello, Multicast Delegate!");}
}

2. Event(事件)
2.1 事件的原理
事件是基于委托的,它是一种特殊的委托,用于实现发布-订阅模式。

事件的主要作用是限制委托的访问权限,确保外部代码只能订阅(+=)或取消订阅(-=)事件,而不能直接调用或覆盖事件。

事件通常用于实现观察者模式,例如 GUI 编程中的按钮点击事件。

2.2 事件的声明与使用
声明事件

// 定义一个委托类型
public delegate void MyEventHandler(object sender, EventArgs e);// 定义一个包含事件的类
public class Button
{// 声明事件public event MyEventHandler Click;// 触发事件的方法public void OnClick(){if (Click != null) // 检查是否有订阅者{Click(this, EventArgs.Empty); // 触发事件}}
}

使用事件

public class Program
{public static void Main(string[] args){Button button = new Button();// 订阅事件button.Click += Button_Click;// 模拟按钮点击button.OnClick();}// 事件处理方法private static void Button_Click(object sender, EventArgs e){Console.WriteLine("Button clicked!");}
}

3. 委托与事件的区别
特性    委托 (Delegate)    事件 (Event)
访问权限    可以从外部直接调用或覆盖    只能从声明它的类内部触发
多播支持    支持多播(绑定多个方法)    支持多播(绑定多个事件处理方法)
用途    通用回调机制,方法传递    实现发布-订阅模式,事件驱动编程
安全性    较低,外部代码可以随意修改委托    较高,外部代码只能订阅或取消订阅事件
4. 使用场景
4.1 委托的使用场景
回调机制:将方法作为参数传递给其他方法,例如异步编程中的回调。

多播委托:需要依次调用多个方法的场景,例如日志记录系统。

动态方法调用:在运行时决定调用哪个方法。

示例:异步编程中的回调

public delegate void AsyncCallback(int result);public class Calculator
{public void AddAsync(int a, int b, AsyncCallback callback){Task.Run(() =>{int result = a + b;callback(result); // 异步完成后调用回调});}
}public class Program
{public static void Main(string[] args){Calculator calculator = new Calculator();calculator.AddAsync(10, 20, result => Console.WriteLine("Result: " + result));}
}

4.2 事件的使用场景
GUI 编程:例如按钮点击、鼠标移动等事件。

发布-订阅模式:例如消息队列、通知系统。

解耦:将事件的触发者和处理者解耦,提高代码的可维护性。

示例:GUI 中的按钮点击事件

public class Button
{public event EventHandler Click;public void OnClick(){Click?.Invoke(this, EventArgs.Empty);}
}public class Program
{public static void Main(string[] args){Button button = new Button();button.Click += (sender, e) => Console.WriteLine("Button clicked!");button.OnClick();}
}

5. 总结
委托:用于定义方法签名,支持多播,适合实现回调机制。

事件:基于委托,用于实现发布-订阅模式,适合解耦和事件驱动编程。

在实际开发中,事件是委托的一种高级应用,通常用于需要更高安全性和解耦的场景。

相关文章:

C#的委托delegate与事件event

在C#中,delegate(委托)和 event(事件)是两个非常重要的概念,它们主要用于实现回调机制和事件驱动编程。下面详细介绍它们的原理和使用场景。 1. Delegate(委托) 1.1 委托的原理 委托…...

apache artemis安装

安装apache artemis https://xxzkid.github.io/2025/apache-artemis-install...

Lightning基础训练尝试实例

一、训练任务概述 动机:由于后续的课题中会用到类似图像去噪的算法,考虑先用U-Net,这里做一个前置的尝试。 训练任务:分割出图像中的细胞。 数据集:可私 数据集结构: 二、具体实现 U-Net的网络实现是现…...

osgearth视点坐标及鼠标交点坐标的信息显示(七)

核心函数如下: void COSGObject::addViewPointLabel() {//mRoot->addChild(osgEarth::Util::Controls::ControlCanvas::get(mViewer));//放开这句,球就卡住了。 为什么,shitosgEarth::Util::Controls::ControlCanvas* canvas = osgEarth::Util::Controls::ControlCanvas…...

动态规划 之 背包问题

文章目录 0-1背包问题2915.和为目标值的最长子序列的长度494.目标和 完全背包问题322.零钱兑换518.零钱兑换II 多重背包2585.获得分数的方法数 分组背包1155.掷骰子等于目标和的方法数 背包问题是动态规划一个很重要的一类题目,主要分为0-1背包问题以及完全背包问题…...

【Azure 架构师学习笔记】- Azure Databricks (11) -- UC搭建

本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Databricks】系列。 接上文 【Azure 架构师学习笔记】- Azure Databricks (10) – UC 使用 前言 由于ADB 的更新速度很快,在几个月之后重新搭建ADB 时发现UC 已经更新了很多,为了后续做ADB 的功…...

RTMP(Real-Time Messaging Protocol)

RTMP(Real-Time Messaging Protocol)是一种用于实时音视频和数据传输的协议,常见于直播和流媒体应用。 一 RTSP 协商消息 一、消息类型(Message Types) RTMP消息分为多种类型,通过Message Type ID标识&a…...

docker容器部署jar应用导入文件时候报缺少字体错误解决

如题,在导入文件时候报错如下: Handler dispatch failed; nested exception is java.lang.NoClassDefFoundError: Could not initialize class sun.awt.X11FontManager 经查是缺少对应字体,解决办法有两张: 第一种:…...

贪吃蛇解析

目录 文章结尾有代码可自取 Win32API 光标的隐藏 获取按键信息 控制光标位置 游戏开始前的准备 游戏准备及介绍 加载和欢迎界面 打印游戏指南 运行游戏 打印墙体和说明 设置蛇的各个信息 初始化及打印蛇 创造食物 运行游戏 1)打印得分情况 2&#…...

vue非组件的初学笔记

1.创建Vue实例,初始化渲染的核心 准备容器引包创建Vue实例new Vue() el用来指定控制的盒子data提供数据 2.插值表达式 作用利用表达式插值,将数据渲染到页面中 格式{{表达式}} 注意点 表达式的数据要在data中存在表达式是可计算结果的语句插值表达式…...

LeetCode 热题 100_单词搜索(60_79_中等_C++)(深度优先搜索(回溯))(初始化二维vector的大小)

LeetCode 热题 100_单词搜索(60_79) 题目描述:输入输出样例:题解:解题思路:思路一(深度优先搜索(回溯)): 代码实现代码实现(思路一&am…...

js闭包,跨域

js闭包,跨域 闭包 想象一下,你家有个大仓库(函数),仓库里放着各种东西(变量)。一般情况下,你从仓库外面是看不到也拿不到仓库里的东西的。但是,闭包就像是你在仓库里留…...

算法练习(力扣-BFS)——102. 二叉树的层序遍历

题目描述(简要概括) 题目链接:102. 二叉树的层序遍历 - 力扣(LeetCode) 题目要求对给定的二叉树进行层序遍历(从上到下,从左到右),并返回遍历的结果。层序遍历是一种基…...

Jetson Agx Orin平台preferred_stride调试记录--1924x720图像异常

1.问题描述 硬件: AGX Orin 在Jetpack 5.0.1和Jetpack 5.0.2上测试验证 图像分辨率在1920x720和1024x1920下图像采集正常 但是当采集图像分辨率为1924x720视频时,图像输出异常 像素格式:yuv_uyvy16 gstreamer命令如下 gst-launch-1.0 v4l2src device=/dev/video0 ! …...

nlp|微调大语言模型初探索(2),训练自己的聊天机器人

前言 上篇文章记录了具体的微调语言大模型步骤,以及在微调过程中可能遇见的各种报错,美中不足的是只是基于开源数据集的微调,今天来记录一下怎么基于自己的数据集去微调大语言模型,训练自己的智能机器人!!&…...

win11安装wsl报错:无法解析服务器的名称或地址(启用wsl2)

1. 启用wsl报错如下 # 查看可安装的 wsl --install wsl --list --online此原因是因为没有开启DNS的原因,所以需要我们手动开启DNS。 2. 按照如下配置即可 Google的DNS(8.8.8.8和8.8.4.4) 全国通用DNS地址 (114.114.114.114) 3. 运行以下命令来重启 WSL…...

Gentleman:优雅的Go语言HTTP客户端工具包

gentlemen介绍,特点等 插件驱动架构:Gentleman的核心特点是其插件系统,允许用户注册和重用各种自定义插件,如重试策略或动态服务器发现,以增强HTTP客户端的功能。 中间件层:项目内置了一个上下文感知的层次…...

解锁豆瓣高清海报(三)从深度爬虫到URL构造,实现极速下载

脚本地址: 项目地址: Gazer PosterBandit_v2.py 前瞻 之前的 PosterBandit.py 是按照深度爬虫的思路一步步进入海报界面来爬取, 是个值得学习的思路, 但缺点是它爬取慢, 仍然容易碰到豆瓣的 418 错误, 本文也会指出彻底解决旧版 418 错误的方法并提高爬取速度. 现在我将介绍…...

IDEA单元测试插件 SquareTest 延长试用期权限

SquareTest是一款强大的IDEA单元测试生成插件工具,具体使用方法就不过多介绍了,这里主要介绍变更试用期,方便大家使用 配置信息 我的电脑安装前提配置条件 IntelliJ IDEA 2023.2windows 系统 软件安装 IntelliJ IDEA 直接安装插件Squar…...

PLC的五个学习步骤

五个学习步骤详解: 1. 夯实电气基础 (第一步) 核心思想: PLC控制技术是建立在传统电气控制技术之上的,因此扎实的电气基础至关重要。学习内容: 电气元件原理: 深入理解继电器、接触器、按钮、三相异步电机等常用电气元件的工作原理。这是理解电气控制回…...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...

【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验

系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...

12.找到字符串中所有字母异位词

🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

selenium学习实战【Python爬虫】

selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...

从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践

作者:吴岐诗,杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言:融合数据湖与数仓的创新之路 在数字金融时代,数据已成为金融机构的核心竞争力。杭银消费金…...

在Zenodo下载文件 用到googlecolab googledrive

方法:Figshare/Zenodo上的数据/文件下载不下来?尝试利用Google Colab :https://zhuanlan.zhihu.com/p/1898503078782674027 参考: 通过Colab&谷歌云下载Figshare数据,超级实用!!&#xff0…...