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

深入理解C#委托操作:添加、移除与调用全解析

关键词:委托不可变性 · 多播委托 · 调用列表管理

⚙️ 一、委托的核心特性:不可变性

看似“添加”,实为新建

使用 += 为委托“添加”方法时(如 delVar += SCl.m3;):

  • 系统创建全新委托对象
  • 新委托的调用列表 = 原列表 + 新增方法
  • 原委托对象保持不变(内存地址不变)

✅ 本质:通过新建实现“修改”,符合委托不可变原则

内存变化图解

MyDel delVar = inst.MyM1;  // 初始委托 (指向方法1)
delVar += SCl.m3;          // 新建委托 (方法1+方法2)
delVar += X.Act;           // 再新建委托 (方法1+2+3)

🧩 二、安全移除方法的机制

-= 运算符的运作逻辑

delVar -= SCl.m3;  // 从调用列表移除方法
  • 创建新委托对象,复制除目标方法外的所有引用
  • 移除规则:
    • 从列表尾部向前搜索
    • 仅移除第一个匹配的方法实例
    • 试图移除不存在的方法时静默忽略

空委托防护

// 正确检查方式
if (delVar != null) 
{delVar(55); 
}
// 或使用空条件运算符 
delVar?.Invoke(65);

⚠️ 未检查空委托直接调用将抛出 NullReferenceException

📡 三、委托调用的双模式与陷阱

image

关键特性:

  • 参数传递:调用时传入的参数应用于所有方法
  • 重复执行:若同一方法在列表中出现多次,每次都会被调用
  • 输出参数:需特殊处理(避免值覆盖问题)

💻 四、完整实例解析

delegate void PrintFunction();  // 无返回值委托 class Test
{public void Print1() => Console.WriteLine("Print1 -- instance");public static void Print2() => Console.WriteLine("Print2 -- static");
}class Program
{static void Main(){var t = new Test();PrintFunction pf = t.Print1;  // 初始化// 添加三个方法(实际新建两次委托)pf += Test.Print2;  pf += t.Print1;     pf += Test.Print2;pf?.Invoke();  // 安全调用 }
}

输出结果:

Print1 – instance
Print2 – static
Print1 – instance
Print2 – static

🔑 关键点总结

  • 不可变性是核心:所有“修改”操作实质是创建新委托对象
  • 移除顺序敏感:从列表尾部开始匹配移除首个目标方法
  • 空委托防护:必须使用 if (delVar != null) 或 ?. 运算符
  • 调用成本:每次调用遍历整个调用列表,需注意性能影响

掌握委托的不可变本质,能有效避免异步编程中的常见陷阱。建议在事件处理等场景中始终遵循「添加后必移除」原则,防止内存泄漏问题。

http://www.lryc.cn/news/576329.html

相关文章:

  • 网络 : 传输层【UDP协议】
  • Linux-读者写者问题
  • STM32F103C8T6参数说明
  • Android4的InputReader
  • 一款支持多日志器、多级别、多落地方式的同异步日志系统
  • 搭建Flink分布式集群
  • 零知开源——基于STM32F407VET6零知增强板的四路独立计时器
  • 配置阿里云OSS实现https访问
  • 解决flash-attn安装报错的问题
  • Java-对象的字符串表示
  • Day45 Tensorboard使用介绍
  • 计算机操作系统(十七)内存管理
  • 关于上位机的热更新
  • 暑假复习篇之运算与逻辑
  • C#数据流处理:深入解析System.IO.Pipelines的奥秘
  • 数据结构与算法 --- 双向链表
  • 鸿蒙 Scroll 组件深度解析:丝滑滚动交互全场景实现
  • Python 数据分析与可视化 Day 10 - 数据合并与连接
  • 华为云Flexus+DeepSeek征文|基于Dify构建文本/图像/视频生成工作流
  • C++虚函数详解:动态绑定机制深度解析
  • 创客匠人视角:创始人 IP 打造为何成为知识变现的核心竞争力
  • 如何在FastAPI中打造坚不可摧的Web安全防线?
  • 【C++】简单学——类和对象(下)
  • 从 AJAX 到 axios:前端与服务器通信实战指南
  • 户外人像要怎么拍 ?
  • 翻译服务器
  • 网络攻防技术
  • 机器学习框架(1)
  • 5 BERT预训练模型
  • Vue基础(18)_收集表单数据