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

引用与回调(提供者/工厂):两类成员变量初始化方式差异解析

类A与类B的成员变量初始化差异及引用、回调的区别

我们直接结合你给出的C#代码,拆解两类初始化方式的核心差异,以及你提到的“引用传递”和“回调”的本质区别:

一、类A的初始化逻辑(ref参数传递)

类A的SetA方法使用ref关键字接收参数,调用时直接传递bCollection的变量引用:

a.SetA(ref bCollection);
  • 赋值时机:调用SetA的瞬间,就把当前bCollection指向的对象引用,直接赋值给_collectionA。这个过程是立即完成的。
  • 引用绑定特性:一旦赋值完成,_collectionA就和bCollection彻底解绑——哪怕后续bCollection被重新赋值为新的BlockingCollection<int>对象,_collectionA依然持有最初那个对象的引用。
  • 注:这里的ref在当前代码里其实有点多余(方法内部没有修改传入的collectionA变量本身),本质和直接传递引用类型参数的效果一致,但核心是直接传递“当前对象的引用”。

二、类B的初始化逻辑(回调委托传递)

类B的SetB方法接收一个Func<BlockingCollection<int>>类型的委托(也就是你说的“回调”),调用时传入的是一个Lambda表达式:

b.SetB(() => bCollection);
  • 赋值时机:调用SetB时,并没有直接获取bCollection的引用,只是把() => bCollection这个“获取引用的逻辑”保存下来。只有当执行collectionBProvider()时,才会去读取当前bCollection指向的对象引用,再赋值给_collectionB。
  • 引用绑定特性:如果collectionBProvider()是延迟执行的(比如把委托保存下来,在后续某个时间点再调用),那么它会拿到bCollection当前最新的引用。比如如果在调用SetB后,你修改了bCollection指向新对象,那么后续执行回调时,_collectionB会绑定到新对象上。
  • 灵活性:回调的本质是传递“行为”而非“值”——你可以在Lambda里写任意逻辑,比如每次调用都创建新对象:() => new BlockingCollection<int>(30),或者根据条件返回不同对象,这是直接传递引用做不到的。

三、核心差异总结

维度类A(ref参数)类B(回调委托)
传递内容当前对象的直接引用获取对象的逻辑/行为
赋值时机调用方法时立即完成执行回调时才完成(可延迟)
后续引用更新影响不受原变量后续赋值影响若延迟执行,会跟随原变量的最新引用
灵活性固定一次性赋值,无扩展空间可自定义获取逻辑,支持动态场景

四、引用与回调的本质区别

  • 引用传递:传递的是对象的“地址值”,是一种值的传递(引用类型的传递本质是传引用的值),目标对象直接绑定当前的引用,逻辑简单直接。
  • 回调:传递的是一段可执行的代码逻辑,是行为的传递,可以在需要的时候再执行逻辑获取值,支持动态、延迟、自定义的场景,灵活性更强。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 19:32:57