C# - 委托与事件1

news/2025/2/21 5:04:31/文章来源:https://www.cnblogs.com/ShenhaoCore/p/18724749

事件与委托

1. 委托(Delegate)

1.1 什么是委托?

委托是 类型安全的函数指针。它允许你将方法作为参数传递或存储,能够动态调用方法。委托本质上是对一个方法的引用,能让你在运行时决定调用哪个方法。

1.2 委托的定义和使用

定义委托

public delegate void MyDelegate(string message);

MyDelegate 是一个委托类型,它定义了一个方法签名:接受一个 string 参数并返回 void

委托的实例化

你可以将委托绑定到任何匹配的函数或方法:

MyDelegate del = new MyDelegate(ShowMessage);void ShowMessage(string message)
{Console.WriteLine(message);
}

通过委托调用方法

del("Hello, Delegate!"); // 调用 ShowMessage 方法

1.3 委托的多播

委托允许多个方法绑定在同一个委托实例上,称为多播委托(Multicast Delegate)。委托会按照添加的顺序依次调用所有绑定的方法。

MyDelegate del = ShowMessage;
del += ShowAnotherMessage;
del("Hello, Multiple Methods!"); void ShowAnotherMessage(string message) 
{ 
    Console.WriteLine("Another message: " + message);
}

1.4 匿名方法和 Lambda 表达式

你也可以通过匿名方法或 Lambda 表达式来定义委托:

MyDelegate del = delegate(string message)
{ Console.WriteLine(message);
};MyDelegate del2 = (message) => Console.WriteLine(message);

2. 事件(Event)

2.1 什么是事件?

事件是基于委托的一种机制,它用于实现 发布-订阅 模式。事件将委托的使用限制为只能由事件的发布者触发,外部订阅者只能响应事件。事件通常用于通知订阅者某些状态或操作的发生。

2.2 事件的定义和使用

定义事件

事件通常通过委托来定义:

public delegate void NotifyEventHandler(string message); 
public event NotifyEventHandler OnNotify;

这里 NotifyEventHandler 是委托类型,OnNotify 是事件名。

触发事件

事件的触发只能在发布者内部进行:

OnNotify?.Invoke("Event triggered!");

订阅事件

订阅者通过 += 操作符来订阅事件:

publisher.OnNotify += subscriber.HandleEvent;

取消订阅

订阅者通过 -= 操作符来取消订阅事件:

publisher.OnNotify -= subscriber.HandleEvent;

2.3 事件的示例

using System;public class Publisher
{// 定义委托类型public delegate void NotifyEventHandler(string message);// 定义事件public event NotifyEventHandler OnNotify;public void TriggerEvent(){// 触发事件OnNotify?.Invoke("Event triggered!");}
}public class Subscriber
{public void HandleEvent(string message){Console.WriteLine("Received event: " + message);}
}public class EventExample
{public void TestEvent(){Publisher publisher = new Publisher();Subscriber subscriber = new Subscriber();// 订阅事件publisher.OnNotify += subscriber.HandleEvent;// 触发事件publisher.TriggerEvent();}
}

3. 委托与事件的关系

  1. 委托是事件的基础:事件是基于委托的,它使用委托来定义事件的签名,实际上事件就是对委托的一种封装。委托负责定义事件的调用方式,事件用于管理委托的注册和触发。

  2. 事件限制委托的调用:委托允许你直接调用方法,而事件限制了委托的调用,只能由事件的发布者来触发,订阅者只能响应事件而不能主动触发。这保证了事件的发布者能够控制何时触发事件,增强了封装性和安全性。

  3. 事件的多播:类似于委托,事件也可以有多个订阅者(多播)。当事件被触发时,所有订阅了该事件的方法都会按顺序执行。

  4. 订阅和取消订阅:委托本身不提供订阅和取消订阅的机制,而事件通过 +=-= 来提供这样的功能,使得代码更加简洁和安全。


4. 委托与事件的实际应用

4.1 发布-订阅模式

事件和委托的常见应用场景是 发布-订阅模式,其中一个对象发布事件,其他对象订阅并响应这些事件。

4.2 用户界面编程

在 GUI 应用(如 WPF 或 WinForms)中,事件与委托常用于处理用户的输入行为,例如按钮点击、鼠标移动等。

4.3 异步操作和回调

事件和委托还广泛用于异步编程和回调操作。例如,当一个任务完成时,事件可以用来通知主线程更新界面或执行后续操作。


5. 总结

  • 委托:是一种类型,它表示对一个方法的引用,可以动态调用方法,支持多播。
  • 事件:是基于委托的,它封装了委托,并限制了委托的触发只能在发布者内部进行,避免外部代码直接触发事件。
  • 事件与委托的关系:事件依赖于委托,委托定义事件的签名,而事件通过 +=-= 让订阅者和发布者之间解耦,简化了事件处理和订阅管理。

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

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

相关文章

git学习 -2025/2/17

git 基础操作指令 git add / git commit -m "注释" /git statusgit log[option]参数版本回退添加文件至忽略列表分支操作远程仓库 添加远程仓库 git remote add <远端名称> <仓库路径> 查看远程仓库 git remote 推送到远程仓库 命令:git push [-f] [--s…

老年人5

编写老年人信息登记表的service层的代码

ASP.NET Core 6 基础入门系列(15) 项目在IIS下部署的两种进程托管模型

系列目录 【已更新最新开发文章,点击查看详细】  ASP.NET Core 6 基础入门系列(14) 项目发布与IIS部署 ASP.NET Core 6 基础入门系列(13) Web 服务器介绍 ASP.NET Core 6 基础入门系列(12) 项目的多种启动方式及问题 ASP.NET Core 6 基础入门系列(11) 项目结构详解之项目…

ASP.NET Core 6 基础入门系列(14) 项目发布与IIS部署

系列目录 【已更新最新开发文章,点击查看详细】ASP.NET Core 6 基础入门系列(13) Web 服务器介绍 ASP.NET Core 6 基础入门系列(12) 项目的多种启动方式及问题 ASP.NET Core 6 基础入门系列(11) 项目结构详解之项目入口Program.cs ASP.NET Core 6 基础入门系列(10) 项目结…

ASP.NET Core 6 基础入门系列(1) ASP.NET Core 6.0 简介

系列目录 【已更新最新开发文章,点击查看详细】预备知识1: C#5、C#6、C#7、C#8、C#9、C#10 预备知识2: .NET 对比 .NET Framework 预备知识3: ASP.NET Core 概述 预备知识4: ASP.NET Core 与 ASP.NET 宏观对比 预备知识5: ASP.NET 请求处理机制 预备知识6: AS…

老年人1

用servlet构建一个javaweb项目并配置好环境

数据类型拓展

数据类型扩展 整数拓展 整数拓展:进制 二进制0b开头 十进制 八进制0开头 十六进制0x开头public class Demo03 {public static void main(String[] args) {//整数拓展: 进制 二进制0b开头 十进制 八进制0开头 十六进制0x开头int i =10;int i2 =010…

寒假打工记

通过联系老师和亲戚获得了家教途径 以下是于中介的沟通总结: 找工作的话尽量不要通过中介简绍,会潜在收取大量的费用,导致工作收益太低,带三个高一学生数学2小时100,不足以提供食宿费;此外还应事先谈好薪资结算时间,以免拖欠。 以下是与学生家长的沟通总结: 与家长沟通…

亲测可用,IDEA中使用满血版DeepSeek R1!支持深度思考!免费!免配置!

之前介绍过在IDEA中使用DeepSeek的方案,但是很多人表示还是用的不够爽,比如用CodeChat的方案,只支持V3版本,不支持带推理的R1。想要配置R1的话有特别的麻烦。作者:程序员 Hollis之前介绍过在IDEA中使用DeepSeek的方案,但是很多人表示还是用的不够爽,比如用CodeChat的方案…

Vscode中Eigen库的导入问题

Vscode中Eigen库的导入问题.Vscode中Eigen库的导入问题 在Vscode中,C++外部库(这里为Eigen)的导入问题主要有库的zip文件下载、在c_cpp_properties.json和tasks.json文件中进行路径配置。另外,如果运行代码使用Code Runner插件,还需要在Code Runner中进行路径配置(即使在…

最新更新!扣子(Coze)接入地表最强DeepSeek-R1大模型,超全攻略,手把手教学,完全免费教程

‍ 最新消息,国产地表最强大模型可以接入Coze平台了,今天斜杠君为大家带来了最细接入攻略,大家快学起来吧~ 备注:需要登录专业版火上引擎接入,开通专业版的同学需要开通一下。 接下来,话不多说,斜杠君用最简单的方式教给大家。 大家可以关注收藏,以免之后找不到,而且也…

1.如何在python中安装playwright

1.如何在python中安装playwright 打开pycharm,进入终端,输入如下的2个命令行代码即可自动完成playwright的安装 pip install playwright ——》在python中安装playwright第三方模块 playwright install ——》安装playwright所需的工具插件和所支持的浏览器 看到这里,是否想…