新闻中心
.NET中委托(Delegate)和事件(Event)的用法_委托事件使用详解
委托是类型安全的函数指针,可引用方法并支持多播调用;事件基于委托,用于封装发布-订阅模式,限制外部直接调用,确保安全的通知机制。

在 .NET 中,委托(Delegate) 和 事件(Event) 是实现回调机制和松耦合设计的重要工具。它们广泛应用于异步编程、GUI 交互、观察者模式等场景。理解它们的用法和区别,对编写高质量的 C# 程序非常关键。
什么是委托(Delegate)?
委托是一种类型安全的函数指针,它定义了方法的签名(参数和返回值),可以引用一个或多个具有相同签名的方法。委托允许将方法作为参数传递,也可以在运行时动态绑定方法。
声明委托:
public delegate void MyDelegate(string message);这行代码定义了一个名为 MyDelegate 的委托,它可以指向任何返回值为 void、参数为 string 的方法。
使用委托示例:
public class Logger{
public void LogToConsole(string msg) => Console.WriteLine("Console: " + msg);
public void LogToFile(string msg) => File.AppendAllText("log.txt", msg + "\n");
}
// 使用
MyDelegate del = new Logger().LogToConsole;
del += new Logger().LogToFile;
del("程序启动"); // 两个方法都会执行
上述代码中,委托实例 del 同时绑定了两个方法,调用时会依次执行,这就是多播委托(Multicast Delegate)。
事件(Event)是什么?
事件是基于委托的封装,用于实现发布-订阅模式。事件允许一个类在特定动作发生时通知其他类,而无需知道具体是谁在监听。
事件通常用于对象间的通信,比如按钮点击、数据更新等。
PictoGraphic
AI驱动的矢量插图库和插图生成平台
133
查看详情
声明事件:
public class Button{
// 声明事件
public event MyDelegate Click;
// 触发事件
public void OnClick()
{
if (Click != null)
Click("按钮被点击");
}
}
订阅事件:
Button btn = new Button();btn.Click += new Logger().LogToConsole;
btn.Click += new Logger().LogToFile;
btn.OnClick(); // 触发事件,两个日志方法都会执行
事件的关键点在于:外部类可以使用 += 和 -= 订阅或取消订阅,但不能直接调用事件或赋值为 null(除非在声明类内部)。
委托与事件的区别
虽然事件基于委托,但两者有本质区别:
- 封装性:事件是对委托的封装,限制外部直接触发或清空委托链。
- 访问控制:类外部只能订阅或取消订阅事件,不能像委托那样随意调用或赋值。
- 语义清晰:事件表示“某事发生了”,更适合用于消息通知;委托更偏向于“调用某个方法”。
- 线程安全考虑:触发事件时应先复制引用,避免在多线程下引发异常:
andler = Click;if (handler != null)
handler("事件触发");
常见应用场景
实际开发中,委托和事件非常实用:
- 窗体应用:WinForms 或 WPF 中的按钮点击、文本变更等都通过事件实现。
- 跨页面通信:父控件监听子控件状态变化。
- 异步回调:任务完成后的通知处理。
- 自定义通知机制:如订单创建后通知库存、邮件服务等模块。
使用 EventHandler 或泛型 EventHandler
{
public string OrderId { get; set; }
}
public class OrderService
{
public event EventHandler
protected virtual void OnOrderCreated(string orderId)
{
OrderCreated?.Invoke(this, new OrderEventArgs { OrderId = orderId });
}
public void CreateOrder()
{
// 创建订单逻辑...
OnOrderCreated("SO001");
}
}
基本上就这些。掌握委托和事件,能让你写出更灵活、可扩展的代码。关键是理解它们的协作方式:委托提供调用能力,事件提供安全的通知机制。
以上就是.NET中委托(Delegate)和事件(Event)的用法_委托事件使用详解的详细内容,更多请关注其它相关文章!
# 是一种
# 网站建设推广费
# 温州网站优化设计工作
# 邮件营销推广邮箱
# seo搜索优化招聘网站
# 优秀网站建设报价
# 计算机营销推广策略分析
# 南京响应式网站建设
# 云南搜狗seo教程
# 宁波象山县网站优化排名
# 中山整合营销seo推广机构
# 相关文章
# 这就是
# 多个
# app
# 直接调用
# 扁平化
# 什么用
# 值为
# 回调
# 多线程
# gate
# .net
# 封装性
# c#
# 区别
# win
# 工具
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
poki网页游戏推荐_poki免费游戏平台入口
免费抖音短视频入口_抖音网页版短视频免费通道
Selenium Python中处理点击后新窗口加载冻结问题的策略与实践
Windows7怎么硬盘安装 Windows7提取ISO镜像到非系统盘并运行setup.exe实现硬盘直装【教程】
Pandas DataFrame:高效添加条件计算列
如何在复杂的电商平台中优雅地管理共享资源并确保正确重定向,使用spryker-shop/resource-share-page模块助你一臂之力
铁路12306改签能改到更早的车次吗_铁路12306改签提前车次规则
Golang如何实现状态模式管理对象状态_Golang State模式实现技巧
Yandex浏览器官方网页版入口 Yandex浏览器最新版官网
新三国志曹操传110级星符试炼夏侯渊极难攻略
虫虫漫画精品漫画官网_虫虫漫画精品漫画官网进入精品漫画
Web Components中自定义开关组件状态同步的常见陷阱与解决方案
React Router 嵌套组件中 URL 重定向问题的解决方案
美团外卖商家服务中心入口 美团商家版官网入口
j*a toString()的覆盖
动漫共和国防屏蔽稳定域名-动漫共和国官方正版直达通道
J*a应用程序首次运行自动创建文件与目录的最佳实践
将HTML动态表格多行数据保存到Google Sheet的教程
J*aScript中针对特定容器内图片动画的实现教程
c++如何实现一个简单的ECS框架_c++数据驱动设计与游戏开发
在Socket.IO连接中实现Access Token自动更新与动态重连
俄罗斯方块最新版入口 俄罗斯方块在线玩官网入口
漫蛙漫画官方首页 漫蛙2漫画在线阅读入口
在J*a中如何隐藏复杂性_使用门面模式组织对象交互
谷歌浏览器浏览体验优化_谷歌浏览器新版直连永久可用提示
在Runstone环境中高效处理TasteDive API的JSON数据
UC浏览器网页版登录入口官网 电脑版网址入口
2025AO3夸克浏览器通道_AO3手机HTTPS安全入口分享
C++如何实现线程池_C++11手动实现一个简单的固定大小线程池
win11 Snap Layouts怎么用 Win11窗口布局与分屏多任务高效指南【必学】
如何使用Node.js csv 包按条件移除含空字段的CSV记录
qq游戏大厅官方下载_qq游戏免费下载安装入口
一加Ace 6T支持全新明眸护眼:通过了最严苛的护眼小金标认证
J*aScript中正确使用querySelectorAll与复杂CSS选择器
J*a TimerTask中HashMap意外清空的深层原因与解决方案
反效果?《战地6》免费试玩开启后玩家数不升反降
铁路12306的积分有效期是多久_铁路12306积分有效期说明
qq邮箱日历功能怎么用_创建日程与会议邀请的技巧
12306选座系统怎么选连座_12306选座多人连坐操作方法
C++如何实现一个装饰器模式_C++设计模式之动态地给对象添加额外职责
铃兰之剑为这和平的世界希里技能组及加点推荐
Android Studio计算器C键功能异常排查与修复教程
yy漫画网页版官方入口_yy漫画官网登录页面链接
怎样更改Windows系统的默认安装路径_避免C盘爆满的终极设置【技巧】
韩剧圈正版入口页面_韩剧圈官网登录链接
在J*a里如何理解依赖关系的方向_依赖方向在模块结构中的作用
豆包手机助手发布技术预览版:直接嵌入手机系统!努比亚样机发售
解决Python单元测试中Mock异常方法调用计数为零的问题
KFC早餐时段怎么领特惠代码_KFC早餐订餐优惠代码获取与使用说明
Golang如何通过reflect获取匿名字段方法_Golang reflect匿名字段方法访问技巧


2025-11-23
浏览次数:次
返回列表