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

C# Lambda表达式中int变量按值还是按引用捕获?程序行为答疑

解释C# Lambda捕获局部变量的行为

先明确这个程序的运行结果:

  • 执行fun1()时,调用委托a后,局部变量x的值变为4;
  • 执行fun2()时,再次调用委托a,修改的是同一个x(此时值变为5)。

核心问题解答

你的疑惑点在于“为什么Lambda捕获的fun1局部变量x,能在fun1执行完后还能被fun2里的委托访问”,本质是C#编译器对Lambda捕获局部变量的特殊处理:

  • Lambda并没有直接捕获栈上的局部变量引用:当Lambda捕获值类型的局部变量时,编译器会自动生成一个隐藏的匿名类,把被捕获的局部变量x包装成这个类的实例字段。Lambda表达式本身会持有这个匿名类实例的引用,所有对x的操作,实际都是操作这个类实例里的字段。

  • 匿名类实例的生命周期不受fun1栈帧限制:fun1执行完毕后,栈上的局部变量(原x)会被销毁,但堆上的匿名类实例因为被静态委托a持有引用,不会被GC回收。所以在fun2中调用a时,依然能访问并修改这个实例里的x字段。

程序执行的详细流程

  1. fun1执行时,初始化局部变量x=3,编译器将x包装进一个匿名类的实例中;
  2. 赋值a = () => { ++x; };,此时委托a指向这个匿名类实例的方法,操作的是实例内的x字段;
  3. 调用a(),实例内的x自增为4,此时int b = x实际是读取实例字段的值,所以b=4;
  4. fun1执行完毕,栈帧销毁,但匿名类实例因被静态委托a引用,保留在堆上;
  5. fun2调用a(),再次对实例内的x自增,此时x变为5。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 21:35:18