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

掌握 C# 中的委托与事件机制

C# 中的委托和事件为开发者提供了处理回调、异步编程以及发布订阅模式的强大工具。委托与事件机制在实际应用中非常常见,特别是在事件驱动编程和 GUI 应用中。本文将带你深入理解委托的定义、匿名方法、Lambda 表达式、事件机制以及多播委托的使用。


1. 委托(Delegate)的定义与使用

委托 是一种类型安全的函数指针,可以用于引用一个或多个方法。通过委托,可以将方法作为参数传递给其他方法,从而实现回调和灵活的行为封装。

委托的定义

委托的定义类似于定义方法签名,它指定了可以被引用的方法的返回类型和参数列表。

// 定义一个委托
public delegate void PrintDelegate(string message);// 使用委托
public class Printer
{public void PrintMessage(PrintDelegate printDelegate, string message){printDelegate(message);  // 调用委托}
}public class Program
{public static void PrintToConsole(string message){Console.WriteLine(message);}public static void Main(){Printer printer = new Printer();PrintDelegate printDelegate = PrintToConsole;  // 将方法赋值给委托printer.PrintMessage(printDelegate, "Hello, Delegates!");  // 输出:Hello, Delegates!}
}

在上面的示例中,PrintDelegate 是一个委托类型,它可以引用任何具有 void 返回类型且接受 string 参数的方法。我们将 PrintToConsole 方法赋值给委托实例,并通过委托调用该方法。


2. 匿名方法与 Lambda 表达式

C# 提供了匿名方法和 Lambda 表达式来简化委托的使用,避免显式定义命名方法。

匿名方法

匿名方法允许你直接将方法逻辑嵌入到委托实例化过程中,而无需创建一个命名方法。

PrintDelegate printDelegate = delegate (string message)
{Console.WriteLine(message);
};printDelegate("Hello, Anonymous Methods!");  // 输出:Hello, Anonymous Methods!

Lambda 表达式

Lambda 表达式是匿名方法的简写形式,语法更加简洁。它使用 => 运算符来分隔参数和方法体。

PrintDelegate printDelegate = (message) => Console.WriteLine(message);printDelegate("Hello, Lambda Expressions!");  // 输出:Hello, Lambda Expressions!

Lambda 表达式在委托、事件和 LINQ 查询中广泛应用,能够极大简化代码编写。


3. 事件机制(Event)

事件 是基于委托的一种特殊机制,通常用于实现发布/订阅模式。事件是对象之间通信的一种方式,允许对象响应特定的状态变化或动作。

事件的定义

事件本质上是对委托的封装,防止订阅者直接调用委托,只允许通过 += 和 -= 来订阅或取消订阅事件。

public class Button
{// 定义一个事件public event EventHandler Click;public void OnClick(){if (Click != null){Click(this, EventArgs.Empty);  // 触发事件}}
}public class Program
{public static void ButtonClicked(object sender, EventArgs e){Console.WriteLine("Button clicked!");}public static void Main(){Button button = new Button();button.Click += ButtonClicked;  // 订阅事件button.OnClick();  // 输出:Button clicked!}
}

在这个示例中,Click 是一个事件,使用 EventHandler 委托。当 OnClick 方法被调用时,事件被触发,所有订阅该事件的方法都会被执行。


4. 多播委托

多播委托 是指一个委托可以同时引用多个方法。每当该委托被调用时,所有被引用的方法都会依次执行。多播委托在事件处理中非常有用,因为事件通常会有多个订阅者。

public delegate void NotifyDelegate(string message);public class Program
{public static void PrintToConsole(string message){Console.WriteLine($"Console: {message}");}public static void PrintToFile(string message){Console.WriteLine($"File: {message} (simulated)");}public static void Main(){NotifyDelegate notifyDelegate = PrintToConsole;notifyDelegate += PrintToFile;  // 添加另一个方法notifyDelegate("Multicast Delegate Example");// 输出:// Console: Multicast Delegate Example// File: Multicast Delegate Example (simulated)}
}

在此示例中,notifyDelegate 委托同时引用了两个方法。当 notifyDelegate 被调用时,两个方法都会依次执行。这就是多播委托的功能。

  • 注意:如果多播委托中包含返回值的方法,只有最后一个方法的返回值会被保留,其余的返回值会被忽略。

结论

委托和事件是 C# 编程中的重要概念,它们使得方法可以作为对象进行传递和处理。在事件驱动编程中,委托和事件的结合非常强大,可以帮助我们构建松耦合、可扩展的程序。

  • 委托 允许将方法作为参数传递,使得代码更加灵活。
  • 匿名方法和 Lambda 表达式 简化了委托的使用,使代码更简洁。
  • 事件机制 为实现发布/订阅模式提供了强大的工具,常用于 GUI 或者异步任务处理。
  • 多播委托 允许一个委托引用多个方法,是事件机制的基础。

通过掌握这些核心概念,你可以编写出更具扩展性和灵活性的 C# 程序。如果你对某个部分有进一步的疑问或需要深入讨论,欢迎继续交流!


这篇博客为你介绍了 C# 中委托与事件的基本概念和应用。如果你有任何问题或者需要更多细节,欢迎留言或者联系我!

相关文章:

掌握 C# 中的委托与事件机制

C# 中的委托和事件为开发者提供了处理回调、异步编程以及发布订阅模式的强大工具。委托与事件机制在实际应用中非常常见,特别是在事件驱动编程和 GUI 应用中。本文将带你深入理解委托的定义、匿名方法、Lambda 表达式、事件机制以及多播委托的使用。 1. 委托&#x…...

使用微服务Spring Cloud集成Kafka实现异步通信(消费者)

1、本文架构 本文目标是使用微服务Spring Cloud集成Kafka实现异步通信。其中Kafka Server部署在Ubuntu虚拟机上,微服务部署在Windows 11系统上,Kafka Producer微服务和Kafka Consumer微服务分别注册到Eureka注册中心。Kafka Producer和Kafka Consumer之…...

docker pull 超时Timeout失败的解决办法

当国内开发者docker pull遇到如下提示时,不要惊讶 [rootvm /]# docker pull postgres Using default tag: latest Error response from daemon: Get "https://registry-1.docker.io/v2/": dial tcp 128.121.146.235:443: i/o timeout [rootvm /]# 自2024…...

YOLOv7改进之主干DAMOYOLO结构,结合 CReToNeXt 结构,打造高性能检测器

一、DAMOYOLO理论部分 论文地址:2211.15444 (arxiv.org) 在本报告中,我们提出了一种快速准确的对象检测方法,称为 DAMO-YOLO,它实现了比最先进的 YOLO 系列更高的性能。DAMO-YOLO 是从 YOLO 扩展而来的,具有一些新技术,包括神经架构搜索 (NAS)、高效的重新参数化广义 …...

进度条(倒计时)Linux

\r回车(回到当前行开头) \n换行 行缓冲区概念 什么现象? 什么现象?? 什么现象??? 自己总结: #pragma once 防止头文件被重复包含 倒计时 在main.c中,windows.h是不可以用的&…...

[每周一更]-(第117期):硬盘分区表类型:MBR和GPT区别

文章目录 1. **支持的磁盘容量**2. **分区数量**3. **引导方式**4. **冗余和数据恢复**5. **兼容性**6. **安全性**7. **操作系统支持**8. 对比 国庆假期前补一篇 在一次扫描机械硬盘故障的问题,发现我本机SSD和机械硬盘的分类型不一样,分别是GPT和MBR&a…...

河南移动:核心营业系统稳定运行超300天,数据库分布式升级实践|OceanBase案例

河南移动,作为电信全业务运营企业,不仅拥有庞大的客户群体和业务规模,还引领着业务产品与服务体系的创新发展。河南移动的原有核心营业系统承载着超过6000万的庞大用户量,管理着超过80TB的海量数据,因此也面临着数据规…...

22.1 k8s不同role级别的服务发现

本节重点介绍 : 服务发现的应用3种采集的k8s服务发现role 容器基础资源指标 role :nodek8s服务组件指标 role :endpoint部署在pod中业务埋点指标 role :pod 服务发现的应用 所有组件将自身指标暴露在各自的服务端口上,prometheus通过pull过来拉取指标但是promet…...

OpenCV计算机视觉库

计算机视觉和图像处理 Tensorflow入门深度神经网络图像分类目标检测图像分割OpenCVPytorchNLP自然语言处理 OpenCV 一、OpenCV简介1.1 简介1.2 OpenCV部署1.3 OpenCV模块 二、OpenCV基本操作2.1 图像的基本操作2.1.1 图像的IO操作2.1.2 绘制几何图像2.1.3 获取并修改图像的像素…...

CentOS 系统中的文件挂载 U 盘

要将 CentOS 系统中的文件保存到 U 盘,可以按照以下步骤进行操作: 一、插入 U 盘并确定设备名称 将 U 盘插入 CentOS 系统的 USB 接口。使用 fdisk -l 命令查看系统中的磁盘和分区情况,确定 U 盘的设备名称。通常 U 盘会显示为类似于 /dev/…...

Lumerical脚本语言-变量操作(Manipulating variables)

下面的命令用来创建和存取变量。 命令描述= 赋值操作符 :数组操作符 []创建矩阵 % 创建包含空格的变量名称 linspace 创建线性空间数组 matrix 创建一个全为 0 的矩阵 randmatrix 创建一个所有元素为 0~1 之间的一个随机数的矩阵 randnmatrix 创建一个所有元素为平均值为 0…...

一个基本的包括爬虫、数据存储和前端展示框架0

创建一个完整的网络爬虫和前端展示页面是一个涉及多个步骤和技术的任务。下面我将为你提供一个基本的框架,包括爬虫代码(使用Python和Scrapy框架)和前端HTML页面(伏羲.html)。 爬虫代码 (使用Scrapy) 首先,你需要安装Scrapy库:bash pip install scrapy 然后,创建一个新…...

简历制作面试篇

一.面试技巧分析 模板: 推荐使用简洁一点的模板,不要太花哨,能够让HR和面试官清楚,快速知道信息就可以,太花哨容易分散别人的注意力。 格式: 一般选用PDF,不要用WORD。 照片: 技术岗一般不用贴照片,推进写上自己的联系方式或者微信。 专业技能: 描述专业技能…...

智能制造--EAP设备自动化程序

EAP是设备自动化程序(Equipment Automation Program)的缩写,他是一种用于控制制造设备进行自动化生产的系统。EAP系统与MES系统整合,校验产品信息,自动做账,同时收集产品生产过程中的制程数据和设备参数数据…...

LabVIEW混合控制器质量检测

随着工业自动化水平的提高,对控制器的精度、稳定性、可靠性要求也在不断上升。特别是在工程机械、自动化生产、风力发电等领域,传统的质量检测方法已无法满足现代工业的高要求。因此,开发一套自动化、精确、可扩展的混合控制器质量检测平台成…...

新技术浪潮下的等保测评:云计算、物联网与大数据的挑战与机遇

随着信息技术的飞速发展,云计算、物联网(IoT)和大数据等新兴技术正以前所未有的速度改变着我们的生活和工作方式。这些技术的广泛应用不仅为信息系统带来了前所未有的性能提升,同时也对等保测评(信息安全等级保护测评&…...

微信小程序技术框架选型

“近期在对团队的微信小程序进行技术框架选型,故对目前主流的微信小程序技术框架进行了一些分析和比较,包括各框架的维护团队、社区链接、GitHub star数、优缺点对比等方面,为团队提供技术框架选型参考” 一、引言 随着移动互联网的快速发展…...

SQL学习3

24.10.3学习目录 一.c语言操作数据库 一.c语言操作数据库 (1)打开、关闭数据库函数 //打开数据库 int sqlite3_open(char *db_name,sqlite3 **db);db_name:数据库文件名,若文件名中有ASCLL码中以外的字符,其必须为UT…...

Linux:进程控制(一)

目录 一、写时拷贝 1.创建子进程 2.写时拷贝 二、进程终止 1.函数返回值 2.错误码 3.异常退出 4.exit 5._exit 一、写时拷贝 父子进程,代码共享,不作写入操作时,数据也是共享的,当任意一方试图写入,便通过写时拷…...

初识算法 · 双指针(3)

目录 前言: 和为s的两数之和 题目解析: ​编辑 算法原理: 算法编写: 三数之和 题目解析 算法原理 算法编写 前言: 本文通过介绍和为S的两数之和,以及三数之和,对双指针算法进行深一步…...

【AI知识点】近似最近邻搜索(ANN, Approximate Nearest Neighbor Search)

近似最近邻搜索(ANN, Approximate Nearest Neighbor Search) 是一种用于高维数据检索的技术,目标是在给定查询的情况下,快速找到距离查询点最近的数据点,尽管结果可能并不完全精确。这种方法特别适用于高维数据&#x…...

编程工具简介

在编程工作中,选择合适的工具确实能够显著提升工作效率。以下是一些被广泛推荐的工具: 1. Visual Studio Code (VS Code):这是一款轻量级但功能强大的代码编辑器,支持多种编程语言,拥有丰富的插件生态系统&#xff0…...

汽车信息安全 -- 存到HSM中的密钥还需包裹吗?

目录 1.车规芯片的ROM_KEY 2.密钥加密与包裹 3.瑞萨RZ\T2M的密钥导入 4.小结 在车控类ECU中,我们通常把主控芯片MCU中的HSM以及HSM固件统一看做整个系统安全架构的信任根。 所以大家默认在HSM内部存储的数据等都是可信的,例如CycurHSM方案中使用HSM…...

【PostgreSQL】入门篇——SELECT、INSERT、UPDATE 和 DELETE 语句,SQL 中最常用的四种操作用法

1. SELECT 语句 描述 SELECT 语句用于从数据库中查询数据。可以选择特定的列或所有列,并可以通过条件过滤结果。 语法 SELECT column1, column2, ... FROM table_name WHERE condition;示例 假设我们有一个名为 employees 的表,结构如下&#xff1a…...

【Ubuntu】安装常用软件包-mysql

我的几个服务是部署在docker的同一个网络里,这样相互访问就可以通过docker容器的名字访问,比如容器A访问容器B,就可以http://B:8080/xxx 这样访问,不用关心ip是多少。 所以mysql前面文章给安装到主机里,感觉有点坑自己…...

幂等性及技术解决方案

文章目录 定义幂等性 为什么需要幂等性幂等性设计注意事项幂等性的范围分布式锁解决幂等性 设计 延伸阅读 定义幂等性 简单地说,我们可以多次执行幂等运算而不改变结果或者使用相同的输入参数中被调用多次,则不具有额外效果的操作,也就是多…...

正向代理 反向代理

正向代理 正向代理是一种网络服务,它作为客户端和目标服务器之间的中间人,代表客户端向目标服务器发送请求并接收响应。以下是关于正向代理的详细解释: 工作原理 客户端配置: 客户端(如浏览器)配置为使用…...

【分布式微服务云原生】如何在ActiveMQ中优雅处理提前支付的延时订单

摘要 本文将深入探讨在ActiveMQ中如何处理用户提前支付的延时订单问题。我们将介绍如何通过更新订单状态、检查延迟任务、取消延迟消息、使用死信队列、消息选择性消费、设置合理的超时时间以及及时反馈和日志记录等策略,来确保系统的一致性和及时响应用户操作。文…...

Easy Excel从入门到精通!!!

目录 1.文件导入 1.1基本方式读取excel文件内容 1.2注解模型映射器读取excel 1.3多行表头读取 1.4文件上传读取 2.文件导出 2.1基本方式导出 2.2模型映射导出 2.3设置行高、列宽等内容 2.4合并单元格 2.5导出设置超链接、批注、公式 2.6模板填充对象导出 2.7模板填…...

简易CPU设计入门:取指令(三),ip_buf与rd_en的非阻塞赋值

在开篇,还是请大家首先准备好本项目所用的源代码。如果已经下载了,那就不用重复下载了。如果还没有下载,那么,请大家点击下方链接,来了解下载本项目的CPU源代码的方法。 下载本项目代码 准备好了项目源代码以后&…...

公司网站开发需要多少钱/百度权重是什么意思

我们先看一个问题:病人因严重的胸痛被送到医院。医生怀疑他是急性缺血性心脏疾病,需要迅速做出决定:是把病人安排到冠心病监护病房,还是把他安排到常规护理病房以监测病人的情况? 在医院,一个关键的决策可以…...

做网站 异地域名/新浪博客

sort(hash.begin(),hash.end());hash.erase(unique(hash.begin(),hash.end()),hash.end());...

大连百事通国际旅行社/seo优化效果怎么样

gradle快速教程,无需在带有Gradle Nexus Staging插件的Nexus GUI中单击即可将Gradle项目中的工件提升/发布到Maven Central。 介绍 Maven Central (又名The Central Repository)(可能是)是Java和基于JVM的项目使用的世界上最大的开源工件集。 它是由Apache Maven的创…...

wordpress淘客插件破解版/谷歌seo排名

这道题在之前基础上,要求在最后判断是否结果小于0,如果最终返回结果小于0,则返回[],直接暴力求解只需要最后返回时进行判断输出即可,但是递归求解时无法在函数中进行判断,所以我在函数外层又加了一层函数。…...

哪个网站是vue做的/软文写作技巧有哪些

引入没有前戏,直奔代码,来看下面这段代码的运行结果:Testpublic void test() { Integer i 666; int j i 1; System.out.println("j " j);}自然,我们都知道会打印 j 667,曾经我很好奇&#xf…...

jquery网站发展历史时间轴/企业站seo价格

差异表达分析之FDR 随着测序成本的不断降低,转录组测序分析已逐渐成为一种很常用的分析手段。但对于转录组分析当中的一些概念,很多人还不是很清楚。今天,小编就来谈谈在转录组分析中,经常会遇到的一个概念FDR,那什么是…...