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

[c#初学者] 委托与事件的区别讨论

文章目录

    • 概要
    • 委托与事件的概念
    • 委托的使用与风险
      • 委托的定义与调用
      • 委托的风险示例
    • 事件
      • 事件的使用
      • 事件的安全机制

概要

C# 中委托与事件是强大的工具 , 常用于事件通知方法调用中.
虽然对于概念和使用有所了解, 但在使用中经常混淆区别.
本文将结合代码实例, 简单的阐述二者开发中的区别

委托与事件的概念

委托(Delegate):C# 中的委托,可以用来引用方法, 可以存放一个或多个方法, 支持直接调用.
事件(Event):事件是基于委托的封装, 他限制了对委托的直接访问, 只允许特定的方式调用绑定的方法.
在功能上,事件增强了委托的安全性和稳定性,下面通过代码展示

委托的使用与风险

委托的定义与调用

publicdelegatevoidaDelegate(stringmessage);publicclassSetDelegate{publicaDelegatead;// 定义一个委托}publicclassProgram{publicvoidMain{SetDelegatesd=newSetDelegate();//绑定方法sd.ad+=(msg)=>Console.WriteLine($"展示一个信息1:{msg}");sd.ad+=(msg)=>Console.WriteLine($"展示一个信息2:{msg}");//调用方法sd.ad?.Invoke("明日不开战");}}

输出结果
展示一个信息1:明日不开战
展示一个信息2:明日不开战

  • 委托本质上是一个方法列表 , Invoke 可以直接触发所有绑定方法
  • 公开的委托虽然易于调用, 但是在外部调用风险很大

委托的风险示例

开放的委托可能会导致外部代码修改内部逻辑

publicdelegatevoidaDelegate(stringmessage);publicclassSetDelegate{publicaDelegatead;// 定义一个委托}publicclassProgram{publicvoidMain{SetDelegatesd=newSetDelegate();//正常绑定方法sd.ad+=(msg)=>Console.WriteLine($"展示一个信息1:{msg}");sd.ad+=(msg)=>Console.WriteLine($"展示一个信息2:{msg}");//正常触发sd.ad?.Invoke("明日不开战");//外部代码覆盖委托sd.ad==(msg)=>Console.WriteLine($"明日开战!");//再次触发sd.ad?.Invoke("明日不开战");}}

输出结果
展示一个信息1:明日不开战
展示一个信息2:明日不开战
明日开战!

  • 外部代码可以直接覆盖委托的绑定内容(使用 = 操作符),导致原有功能被破坏

事件

事件的使用

事件是基于委托的封装, 限制了外部对委托的访问权限,从而增强安全性

publicdelegatevoidAlarmHandler(stringmessage);publicclassAlarm{// 使用事件代替公开的委托publiceventAlarmHandlerOnAlarm;// 提供触发事件的方法publicvoidTriggerAlarm(stringmessage){OnAlarm?.Invoke(message);}}publicclassProgram{staticvoidMain(){Alarmalarm=newAlarm();// 绑定事件处理器alarm.OnAlarm+=(msg)=>Console.WriteLine($"展示一个信息1:{msg}");alarm.OnAlarm+=(msg)=>Console.WriteLine($"展示一个信息2:{msg}");// 通过触发方法调用事件alarm.TriggerAlarm("明日不开战");}}

输出结果
展示一个信息1:明日不开战
展示一个信息2:明日不开战

事件的安全机制

  • 外部只可以通过 += -= 订阅或取消事件 , 无法直接调用Invock
  • 外部无法使用 = 覆盖事件逻辑, 避免了外部修改

委托与事件最大的区别在于对安全性的设计取舍。

http://www.jsqmd.com/news/647873/

相关文章:

  • 51单片机复位电路电容选型实战:从10uF到8uF的取舍与计算
  • 2026年信创OA怎么选:传统OA厂商、互联网平台、新玩家,差别到底在哪?
  • 从CLIP到FLAVA:图解多模态模型中的特征融合三阶段(附注意力机制详解)
  • Move Mouse终极指南:告别电脑休眠困扰的完整解决方案
  • MySQL 8.0.45 完整mysqld_safe启动
  • 别再只盯着模型结构了!π0.5的成功秘诀:数据混合配方与训练策略深度解析
  • 2026 程序员 AI新范式 ---第二章:奶酪消失——AI浪潮下的焦虑与挣扎
  • 告别PyAutoGUI!用Python ctypes直接调用Windows API实现更稳定的键鼠模拟(附完整代码)
  • D455+VINS-Fusion+Octomap:从点云到八叉树栅格地图的完整实现
  • 保姆级教程:用Python+Matlab从零推导Panda机械臂的DH参数与正运动学
  • ULTRA论文部署与复现报告Uncertainty-aware Label Distribution Learning for Breast Tumor Cellularity Assessment
  • 好写作AI:论文的“降重降AI”,从“事后补救”变成“源头定制”
  • 前端项目中如何优雅地封装接口请求?一篇讲清 JS 请求管理思路
  • 为什么说MetaFormer才是视觉任务的本质?从PoolFormer看架构设计的范式转移
  • 2026全网最全的AI软件测试面试题(含答案+文档)
  • Arduino IDE串口识别失败?别慌!可能是CH340驱动端口被占用了(附一键排查脚本)
  • 机械键盘连击终结者:KeyboardChatterBlocker 完全指南与实战配置
  • 告别位置编码!用SegFormer的Mix-FFN搞定语义分割中的多尺度输入难题
  • 【STM32-HAL库】RS485中断接收实战:基于STM32F103VET6的稳定通信方案
  • 【LeetCode Hot 100】 除自身以外数组的乘积(238题)多解法详解
  • 【仅限本周开放】多模态域适应私密工作坊实录:手把手复现ICML 2024 Oral论文《Cross-Modal Invariant Transport》完整Pipeline
  • 工业相机开发实战:埃科GigE相机SDK调用全流程解析(附代码示例)
  • 避坑指南:VLLM中CUDA Graphs捕获失败的5个常见原因及解决方案
  • 【保姆级】嵌入式工程师的Git第一课:从“硬件版本混乱“到“代码时光机“(环境搭建与核心概念详解)
  • 手把手教你用lspci和setpci排查PCIe设备性能瓶颈:从MaxPayloadSize到TLP传输优化
  • OCR大模型推理速度提升470%?揭秘2026奇点大会现场实测的8层量化蒸馏架构
  • STM32实战:FreeModbus移植避坑指南(基于正点原子F4库函数版)
  • vite8相对于vite7否更新哪些东西?
  • 基于LTspice的文氏桥振荡电路设计与频率稳定性优化
  • 从零开始DIY一个可调稳压电源:用LM317和XL4016搭建你的桌面实验神器