使用Lambda和匿名方法关闭C#

时间:2018-09-27 19:15:24

标签: c# closures

我想基于两个示例,提出与闭包维护局部变量有关的问题:

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

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

谢谢!

1 个答案:

答案 0 :(得分:4)

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

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


要清楚:这与使用委托而不是terser lambda语法的第一个示例无关。您可以编写第一个示例,其中inc被实现为lambda而不是委托,并且仍然会看到这种差异。