变量何时是闭包的一部分



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

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

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

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

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

匿名函数总是使用闭包。

没有办法只捕获变量的值。

如果你不想让函数看到变量的变化,你可以制作一个单独的临时变量,并在函数中使用它,

看看Eric Lippert关于这一点的由两部分组成的文章,并特别修改了闭包"bugs"。他比我读过的任何人都能更好地解释这一点。

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

"匿名函数总是使用闭包",或者它们对引用的任何变量进行闭包。可以使用工厂方法正确地确定这些引用变量的范围,这样Func<int>就可以在创建Func<int>时返回foo的值。采取以下措施。

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;
}

或者更好的非静态版本IMHO(其他人可能不同意)

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

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

Func<int> myFunction = CreateFooFunc(foo);

请记住,如果foo本身的值是可变的(例如POCO),则必须复制它或CreateFooFunc内部的某些内容才能具有相同的效果。

最新更新