什么是闭包?我们在。net中有吗?

如果它们确实存在于。net中,你能提供一个代码片段(最好是c#)来解释它吗?


当前回答

如果你有兴趣了解c#如何实现闭包,请阅读“I know the answer (its 42) blog”。

编译器在后台生成一个类来封装匿名方法和变量j

[CompilerGenerated]
private sealed class <>c__DisplayClass2
{
    public <>c__DisplayClass2();
    public void <fillFunc>b__0()
    {
       Console.Write("{0} ", this.j);
    }
    public int j;
}

对于函数:

static void fillFunc(int count) {
    for (int i = 0; i < count; i++)
    {
        int j = i;
        funcArr[i] = delegate()
                     {
                         Console.Write("{0} ", j);
                     };
    } 
}

把它变成:

private static void fillFunc(int count)
{
    for (int i = 0; i < count; i++)
    {
        Program.<>c__DisplayClass1 class1 = new Program.<>c__DisplayClass1();
        class1.j = i;
        Program.funcArr[i] = new Func(class1.<fillFunc>b__0);
    }
}

其他回答

Func<int, int> GetMultiplier(int a)
{
     return delegate(int b) { return a * b; } ;
}
//...
var fn2 = GetMultiplier(2);
var fn3 = GetMultiplier(3);
Console.WriteLine(fn2(2));  //outputs 4
Console.WriteLine(fn2(3));  //outputs 6
Console.WriteLine(fn3(2));  //outputs 6
Console.WriteLine(fn3(3));  //outputs 9

闭包是传递到创建闭包的函数外部的匿名函数。 它维护它所使用的函数中的任何变量。

闭包是在函数中定义的函数,可以访问它的局部变量以及它的父变量。

public string GetByName(string name)
{
    List<things> theThings = new List<things>();
    return  theThings.Find<things>(t => t.Name == name)[0];
}

find方法中的函数。

t => t.Name == name

可以访问其作用域中的变量t,以及父作用域中的变量名。即使它是由find方法作为委托从另一个作用域执行的。

基本上闭包是一段代码,你可以把它作为参数传递给函数。c#支持匿名委托形式的闭包。

这里有一个简单的例子: 列表。Find方法可以接受并执行一段代码(闭包)来查找列表的项。

// Passing a block of code as a function argument
List<int> ints = new List<int> {1, 2, 3};
ints.Find(delegate(int value) { return value == 1; });

使用c# 3.0语法,我们可以这样写:

ints.Find(value => value == 1);

如果你有兴趣了解c#如何实现闭包,请阅读“I know the answer (its 42) blog”。

编译器在后台生成一个类来封装匿名方法和变量j

[CompilerGenerated]
private sealed class <>c__DisplayClass2
{
    public <>c__DisplayClass2();
    public void <fillFunc>b__0()
    {
       Console.Write("{0} ", this.j);
    }
    public int j;
}

对于函数:

static void fillFunc(int count) {
    for (int i = 0; i < count; i++)
    {
        int j = i;
        funcArr[i] = delegate()
                     {
                         Console.Write("{0} ", j);
                     };
    } 
}

把它变成:

private static void fillFunc(int count)
{
    for (int i = 0; i < count; i++)
    {
        Program.<>c__DisplayClass1 class1 = new Program.<>c__DisplayClass1();
        class1.j = i;
        Program.funcArr[i] = new Func(class1.<fillFunc>b__0);
    }
}

Closures are chunks of code that reference a variable outside themselves, (from below them on the stack), that might be called or executed later, (like when an event or delegate is defined, and could get called at some indefinite future point in time)... Because the outside variable that the chunk of code references may gone out of scope (and would otherwise have been lost), the fact that it is referenced by the chunk of code (called a closure) tells the runtime to "hold" that variable in scope until it is no longer needed by the closure chunk of code...