首页 > 解决方案 > C# 中的闭包,带有 lambdas 和匿名方法

问题描述

我想根据两个示例提出与维护局部变量的闭包相关的问题:

public static Func<int, int> F2()
{
    var local = 1;
    Func<int, int> inc = delegate (int x)
    {
        local = local + 1;
        return x + local;
    };
    return inc;
}

现在,调用它会呈现正确的 Closure 工作机制

var inc2 = F2();
Console.WriteLine(inc2(10));
Console.WriteLine(inc2(10));

输出结果:

12
13

现在,替代版本:

public static Func<int, int> F1 = i =>
{
    var local = 1;
    Func<int, int> FInn = x =>
    {
        local++;
        return local + x;
    };
    return FInn(i);
};

调用这个:

    var inc1 = F1;
    Console.WriteLine(inc1(10));
    Console.WriteLine(inc1(10));

现在渲染:

12
12

为什么第二个版本以不同于第一个的方式工作?

谢谢 !

标签: c#closures

解决方案


在第一个示例中,local在顶部初始化,内部 lambda 捕获它。您将内部 lambda 返回给调用代码,其中包括捕获的变量。

在第二个示例中,每次调用 时F1,都从一开始就运行它。这意味着您local每次都将变量初始化为 1。然后你立即对它执行内部FInn


需要明确的是:这与第一个使用委托而不是更简洁的 lambda 语法的示例无关。您可以编写第一个示例,将其inc实现为 lambda 而不是委托,您仍然会看到这种差异。


推荐阅读