C# 闭包

C# 中的闭包(Closure)概念解析

1. 核心定义

闭包是 「函数 + 其创建时捕获的外部变量环境」 的组合体。在 C# 中:

  • 函数:表现为 lambda 表达式匿名方法委托
  • 外部环境:函数捕获的外部作用域中的变量(如局部变量、参数)。
  • 本质:编译器自动生成一个隐藏类来封装捕获的变量,延长其生命周期。

2. 示例演示

Func<int> CreateCounter()
{
    int count = 0;
    return () => ++count; // 闭包捕获 count
}

var counter = CreateCounter();
Console.WriteLine(counter()); // 1
Console.WriteLine(counter()); // 2(变量状态保留)

3. 关键特性

  • 变量捕获为引用:闭包捕获变量本身,而非当前值。
  • 状态持久化:局部变量逃逸原始作用域,生命周期与闭包绑定。
  • 编译器生成封装类:捕获的变量会被提升为类的字段(例如 <>c__DisplayClass1)。

4. 常见误区

  • ❌ 误区 1:所有委托都是闭包
    纠正:只有捕获外部变量的委托才会形成闭包。

  • ❌ 误区 2:闭包直接存储变量值
    纠正:闭包持有变量的引用,共享同一内存位置(见下方示例):

var actions = new List<Action>();
for (int i = 0; i < 3; i++)
{
    actions.Add(() => Console.WriteLine(i));
}
actions.ForEach(a => a()); // 输出 3, 3, 3(而非 0,1,2)

5. 总结

  • 闭包 = 函数 + 捕获的变量环境 + 编译器生成的封装机制。
  • 核心价值:让函数携带上下文,突破变量作用域限制。
  • 注意事项:警惕循环中捕获变量时的共享引用问题!
posted @ 2025-04-21 11:49  吃饺子不沾醋  阅读(171)  评论(0)    收藏  举报