商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > C#怎么使用Delegate多播委托_C#多播委托链式调用方法教程【进阶】

C#怎么使用Delegate多播委托_C#多播委托链式调用方法教程【进阶】

  发布于2026-07-18 阅读(0)

扫一扫,手机访问

多播委托赋值必须用+=而非=,否则覆盖原有方法;调用前需用?.判空;移除时方法引用须完全一致;异常会中断后续调用,需手动遍历+try/catch处理。

C#怎么使用Delegate多播委托_C#多播委托链式调用方法教程【进阶】

多播委托赋值时别用 =,要用 +=

直接拿 = 赋值,等于把之前的委托全都扔了,这不是追加,这是替换。C# 的多播委托底层其实是个链表,只有 += 才能把多个方法“缝合”到同一个委托实例上。

一个常见翻车现场:

myDelegate = MethodA;  
myDelegate = MethodB;  
myDelegate(); // 只调了 MethodB,MethodA 没了

正确的姿势是:

Action handler = null;  
handler += MethodA;  
handler += MethodB;  
handler(); // 依次调用 MethodA → MethodB
  • += 背后其实是 Delegate.Combine,自动帮你处理空值和类型检查
  • 就算左边是 null+= 也能安全初始化,不用提前判空
  • 别手动去调 Delegate.Combine(a, b),容易出错,可读性也差

调用多播委托前必须判空,否则 NullReferenceException

就算你刚用 += 加过方法,也别拍胸脯说 handler 一定非空——万一所有订阅者都用 -= 撤了,或者初始就是 null,那直接调用就炸了。

错误示范:handler(); —— 运行时直接给你一个 NullReferenceException

安全写法(推荐):

handler?.Invoke();
  • ?. 是 C# 6.0+ 引入的空条件操作符,写法简洁,而且比 if (handler != null) handler(); 更靠谱(线程安全考虑)
  • 别在 handler?.Invoke() 外面套一层 try/catch——异常是设计缺陷,不是流程分支
  • 如果委托有返回值(比如 Func),?. 会返回 null 或默认值,需要根据场景单独处理

移除委托必须用 -=,且方法引用要完全一致

-= 不是模糊匹配,它严格比较方法指针,连闭包捕获的变量都得一模一样。稍微差一点,移除就失败,结果就是内存泄漏或者方法重复执行。

典型陷阱:

handler += () => Console.WriteLine("A");  
handler -= () => Console.WriteLine("A"); // ❌ 失败!这是另一个匿名方法实例
  • 命名方法可以安全移除:handler += MethodA; handler -= MethodA;
  • Lambda 要复用的话,先定义一次再引用:var lambda = () => ...; handler += lambda; handler -= lambda;
  • ActionFunc<> 时,不要在循环里反复创建新委托实例然后又移除,那是给自己挖坑

多播委托异常会中断后续调用,无法自动跳过

这是最容易被忽略的设计事实:一旦某个订阅方法抛了异常,整个链就停了,后面的方法永远没机会执行。

比如:

handler += () => { Console.Write("1"); };  
handler += () => { throw new Exception(); };  
handler += () => { Console.Write("3"); }; // ❌ 永远不会执行
  • 框架没有内置的“容错遍历”机制,唯一的可控方式是 GetInvocationList() + 手动 try/catch
  • 如果业务要求健壮性,必须显式遍历:foreach (var d in handler.GetInvocationList()) { try { d.DynamicInvoke(); } catch { /* 忽略或记录 */ } }
  • 性能上要注意:反射调用 DynamicInvoke 比直接 Invoke 慢一个数量级,高频场景要慎用

多播委托不是简单的“语法糖”,它的调用顺序、异常传播、生命周期管理全由底层 Delegate 类控制。写的时候少想“链式”,多想“事件队列”——每个环节都得自己兜底。

本文转载于:https://www.php.cn/faq/2343977.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注