You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中_onScroll += _ => _onScroll3?.Invoke()这类委托订阅作用是什么

问题解答

核心代码作用解释

你提到的两行代码本质都是事件转发的实现:

  • _onScroll += _ => _onScroll3?.Invoke();:_onScroll是带int参数的事件类型,Lambda表达式里的_是显式丢弃不需要用到的传入int参数。意思是每次_onScroll事件被触发时,就自动触发一次_onScroll3事件。
  • _onScroll2 += () => _onScroll3?.Invoke();:_onScroll2是无参事件类型,Lambda不需要接收参数,作用和上面一致:_onScroll2触发时自动转发触发_onScroll3。

调用Invoke的原因

有两个核心原因:

  1. 空安全触发要求:C#的事件本质是多播委托,如果没有任何订阅者,事件变量的值就是null,直接调用_onScroll3()会抛出空引用异常。?.Invoke()是C# 6及以上版本提供的空条件调用语法,会先判断_onScroll3是否不为空,只有存在订阅者时才会执行触发逻辑,避免空引用报错,且该判断是原子操作,线程安全。
  2. 事件触发的规范写法:事件只能在声明它的类内部直接触发,Invoke就是委托/事件的标准触发方法,执行时会按顺序调用所有订阅了_onScroll3的回调方法。

你观察到的“订阅者同步”现象说明

这不是订阅者真的同步了,是转发逻辑带来的效果:你只给_onScroll、_onScroll2各加了一个转发到_onScroll3的回调,所以不管后续给_onScroll3新增/移除多少订阅者,_onScroll、_onScroll2触发时都会执行当时_onScroll3的所有订阅回调,看起来就像是两个事件的订阅者和_onScroll3同步了。

这种写法的常用场景是把多个不同签名的同源事件(比如不同场景下的滚动事件)统一转发到同一个入口事件,业务代码只需要订阅一次入口事件就可以接收所有相关通知,减少重复订阅的冗余代码。

额外注意点

你示例中的DoWork、DoWork2方法每次调用都会给事件新增一次匿名Lambda订阅,而匿名方法没有办法直接移除订阅,多次调用会导致_onScroll3被重复触发多次,实际使用时要避免这种重复订阅的问题。


内容的提问来源于stack exchange,提问作者Dani Grosu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 01:06:07