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

C#中Func/Action委托在源对象脱离作用域后是否会变为null?

当源对象失去引用时,Func和Action委托是否会变为null?

问题场景

首先给出涉及的类定义:
类A中定义如下实例方法:

public int CubeAnInt32(int n)
{
    return n * n * n;
}

类B中定义如下接收委托参数的方法:

public void CubeAnInt32WithDelegate(int k, Func<int, int> delg)
{
    return delg(k);
}

全局作用域相关代码定义如下:

/// 注意:该变量定义在SomeArbitraryCallback()方法作用域外
Func<int, int> cube = default;

public void SomeArbitraryCallback()
{
    var refWithinScope = new ClassA();
    cube = refWithinScope.CubeAnInt32;
    return;
}

public void AnotherCallbackPerformedAfter()
{
    var cubeDependent = new ClassB();

    /// 此处是否会因为'cube'抛出NullReferenceException?
    /// 赋值给'cube'的委托是否已被取消引用?
    var result = cubeDependent.CubeAnInt32WithDelegate(0, cube);
    return result;
}

核心疑问:当委托绑定的对象脱离作用域(如本例中cube委托绑定的ClassA实例refWithinScope)时,委托是否会被取消引用变为null?还是说委托会持有绑定对象的引用,阻止该对象被GC回收?

解答

结论:示例中的cube委托不会变为null,调用时不会抛出NullReferenceException,委托会持有绑定实例方法的目标对象的强引用,阻止该对象被GC回收。
具体规则如下:

  • 当将实例方法赋值给Func/Action这类委托时,委托内部会同时存储两部分信息:待调用方法的元数据、调用方法时作为this传入的目标实例引用。
  • 示例中cube是方法作用域外的长生命周期变量,SomeArbitraryCallback()执行结束后,虽然局部变量refWithinScope超出作用域失效,但cube内部存储的ClassA实例引用依然是有效强引用。GC会将该ClassA实例判定为可达对象,不会回收它,委托本身也不存在自动被置为null的机制。
  • 只有当cube本身被手动赋值为null,且没有其他任何变量持有该委托、同时目标ClassA实例也没有其他可达引用时,对应的ClassA实例才会被GC回收。
  • 补充说明:如果赋值给委托的是静态方法,委托不需要存储实例引用,自然不存在持有对象、阻止GC的逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 15:30:51