编辑
2025-10-13
C#
00

目录

什么是闭包?
闭包的基本原理
简单闭包示例
闭包的高级应用
循环中的闭包陷阱
函数工厂与参数绑定
注意
总结

什么是闭包?

闭包(Closure)是一种强大的编程概念,它允许函数捕获并记住其定义时的环境上下文。在C#中,闭包使得函数可以访问并操作其词法作用域之外的变量。这个东西在JS中用的太多了。

闭包的基本原理

闭包本质上是一个函数,它能够"记住"并访问其创建时的环境变量,即使这些变量已经超出了原始作用域。

简单闭包示例

C#
public class ClosureDemo { public static Func<int> CreateCounter() { // count 是被捕获的局部变量 int count = 0; // 返回一个匿名函数(闭包) return () => { count++; // 闭包可以修改外部变量 return count; }; } public static void Main() { // 创建两个独立的计数器 var counter1 = CreateCounter(); var counter2 = CreateCounter(); Console.WriteLine(counter1()); // 输出: 1 Console.WriteLine(counter1()); // 输出: 2 Console.WriteLine(counter2()); // 输出: 1 (独立的计数器) } }

image.png

闭包的高级应用

循环中的闭包陷阱

C#
namespace AppClosure { internal class Program { public static void LoopClosure() { // 常见的闭包陷阱 var actions = new List<Action>(); for (int i = 0; i < 5; i++) { // 这里会捕获循环变量i的引用,而非值 actions.Add(() => Console.WriteLine(i)); } // 实际输出会是 5 5 5 5 5 foreach (var action in actions) { action(); } // 解决方案:使用局部变量捕获当前值 var correctActions = new List<Action>(); for (int i = 0; i < 5; i++) { int localI = i; // 创建局部副本 correctActions.Add(() => Console.WriteLine(localI)); } // 现在会正确输出 0 1 2 3 4 foreach (var action in correctActions) { action(); } } static void Main(string[] args) { LoopClosure(); } } }

image.png

函数工厂与参数绑定

C#
namespace AppClosure { internal class Program { // 创建一个带有预设参数的函数 public static Func<int, int> Multiplier(int factor) { // 闭包捕获factor return x => x * factor; } public static void Demonstrate() { var doubler = Multiplier(2); var tripler = Multiplier(3); Console.WriteLine(doubler(5)); // 输出: 10 Console.WriteLine(tripler(5)); // 输出: 15 } static void Main(string[] args) { Demonstrate(); } } }

image.png

注意

  1. 谨慎使用闭包,避免不必要的复杂性
  2. 注意循环中的闭包陷阱
  3. 使用局部变量捕获当前值
  4. 考虑性能和内存开销

总结

闭包是C#中一个强大且灵活的特性,它允许函数携带其创建时的上下文。正确理解和使用闭包,可以编写更加简洁和表达性强的代码。

本文作者:技术老小子

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!