什么是关闭?我们在.NET中有它们吗?
如果它们确实存在于.NET中,您能否提供一个代码片段(最好用C#)来解释它?
编辑:我浏览了Jon Skeet的文章,了解什么是闭包以及如何在.NET中使用它们.
Jon*_*eet 247
我有一篇关于这个主题的文章.(它有很多例子.)
从本质上讲,闭包是一个代码块,可以在以后执行,但它维护它首次创建的环境 - 即它仍然可以使用创建它的方法的局部变量等,即使在那之后方法已完成执行.
闭包的一般特性是通过匿名方法和lambda表达式在C#中实现的.
这是一个使用匿名方法的示例:
using System;
class Test
{
static void Main()
{
Action action = CreateAction();
action();
action();
}
static Action CreateAction()
{
int counter = 0;
return delegate
{
// Yes, it could be done in one statement;
// but it is clearer like this.
counter++;
Console.WriteLine("counter={0}", counter);
};
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
counter=1
counter=2
Run Code Online (Sandbox Code Playgroud)
在这里我们可以看到CreateAction返回的操作仍然可以访问计数器变量,并且确实可以增加它,即使CreateAction本身已经完成.
小智 22
如果您有兴趣了解C#如何实现Closure,请阅读"我知道答案(其42)博客"
编译器在后台生成一个类来封装anoymous方法和变量j
[CompilerGenerated]
private sealed class <>c__DisplayClass2
{
public <>c__DisplayClass2();
public void <fillFunc>b__0()
{
Console.Write("{0} ", this.j);
}
public int j;
}
Run Code Online (Sandbox Code Playgroud)
对于功能:
static void fillFunc(int count) {
for (int i = 0; i < count; i++)
{
int j = i;
funcArr[i] = delegate()
{
Console.Write("{0} ", j);
};
}
}
Run Code Online (Sandbox Code Playgroud)
把它变成:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
闭包是保留原始范围的变量值的功能值.C#可以以匿名委托的形式使用它们.
举个简单的例子,拿这个C#代码:
delegate int testDel();
static void Main(string[] args)
{
int foo = 4;
testDel myClosure = delegate()
{
return foo;
};
int bar = myClosure();
}
Run Code Online (Sandbox Code Playgroud)
在它结束时,bar将被设置为4,并且myClosure委托可以被传递以在程序的其他地方使用.
闭包可用于许多有用的事情,如延迟执行或简化接口 - LINQ主要使用闭包构建.它对大多数开发人员来说最直接的方式是为动态创建的控件添加事件处理程序 - 您可以使用闭包在实例化控件时添加行为,而不是将数据存储在其他位置.
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
Run Code Online (Sandbox Code Playgroud)
闭包是在创建它的函数之外传递的匿名函数.它维护它所使用的函数所在的任何变量.