新闻中心

.NET中委托(Delegate)和事件(Event)的用法_委托事件使用详解

2025-11-23
浏览次数:
返回列表
委托是类型安全的函数指针,可引用方法并支持多播调用;事件基于委托,用于封装发布-订阅模式,限制外部直接调用,确保安全的通知机制。

.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 PictoGraphic

AI驱动的矢量插图库和插图生成平台

PictoGraphic 133 查看详情 PictoGraphic

声明事件:

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(除非在声明类内部)。

委托与事件的区别

虽然事件基于委托,但两者有本质区别:

  • 封装性:事件是对委托的封装,限制外部直接触发或清空委托链。
  • 访问控制:类外部只能订阅或取消订阅事件,不能像委托那样随意调用或赋值。
  • 语义清晰:事件表示“某事发生了”,更适合用于消息通知;委托更偏向于“调用某个方法”。
  • 线程安全考虑:触发事件时应先复制引用,避免在多线程下引发异常:
var handler = Click;
if (handler != null)
    handler("事件触发");

常见应用场景

实际开发中,委托和事件非常实用:

  • 窗体应用:WinForms 或 WPF 中的按钮点击、文本变更等都通过事件实现。
  • 跨页面通信:父控件监听子控件状态变化。
  • 异步回调:任务完成后的通知处理。
  • 自定义通知机制:如订单创建后通知库存、邮件服务等模块。

使用 EventHandler 或泛型 EventHandler 是更标准的做法:

public class OrderEventArgs : EventArgs
{
    public string OrderId { get; set; }
}

public class OrderService
{
    public event EventHandler OrderCreated;

    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匿名字段方法访问技巧 

搜索