变量何时成为闭包的一部分?

时间:2011-06-16 15:52:04

标签: c#

假设我想创建一个匿名的getter函数,该函数将返回成员变量foo的当前值。我可以写:

Func<int> myFunction = delegate() { return foo; };

但是我想要一个获取foo值的函数,将该值绑定到它的闭包中,然后每次调用它时返回该值。我写的是同样的事情:

Func<int> myFunction = delegate() { return foo; };

C#编译器如何区分?有什么方法可以更具体地询问你想要什么吗?

3 个答案:

答案 0 :(得分:4)

匿名函数总是使用闭包。

无法仅捕获变量的值。

如果您不希望函数看到变量的变化,您可以创建一个单独的临时变量并在函数中使用它,

答案 1 :(得分:2)

看看Eric Lippert's two-part article关于此问题,并特别修改了关闭“错误”。他比我读过的任何人都更好地解释了这一点。

@SLaks是关于无法捕获变量的的。

答案 2 :(得分:0)

“匿名函数总是使用闭包”或者它们会关闭它们引用的任何变量。可以使用工厂方法正确地区分这些引用的变量,以便Func<int>foo创建时返回Func<int>的值。请采取以下措施。

private static Func<int> CreateFooFunc(int scopedFoo)
{
    return () => scopedFoo;
    //FYI, the line above is more concise version of line below
    //return () => { return scopedFoo; };
    //which is a more concise version of line below
    //return delegate() { return scopedFoo; };
}

或非静态,具体取决于用例。

private Func<int> CreateFooFunc()
{
    var scopedFoo = foo;
    return () => scopedFoo;
}

或更好的非静态版本恕我直言(其他人可能不同意)

private Func<int> CreateFooFunc()
{
    return CreateFooFunc(foo)
}

您现在可以执行以下操作,myFunction将包含一个函数,在评估时,它将在创建时返回foo的值。

Func<int> myFunction = CreateFooFunc(foo);

请记住,如果foo本身的值本身是可变的(例如POCO),那么您必须复制它或CreateFooFunc内的某些内容才能产生相同的效果。< / p>