什么是闭包?我们在。net中有吗?
如果它们确实存在于。net中,你能提供一个代码片段(最好是c#)来解释它吗?
什么是闭包?我们在。net中有吗?
如果它们确实存在于。net中,你能提供一个代码片段(最好是c#)来解释它吗?
当前回答
这是c# 7.0概要书中一个简单易懂的答案。
您应该知道的先决条件:lambda表达式可以引用方法的局部变量和参数 其中它被定义(外部变量)。
static void Main()
{
int factor = 2;
//Here factor is the variable that takes part in lambda expression.
Func<int, int> multiplier = n => n * factor;
Console.WriteLine (multiplier (3)); // 6
}
实部分:lambda表达式引用的外部变量称为捕获变量。捕获变量的lambda表达式称为闭包。
最后需要注意的一点:被捕获的变量是在委托实际调用时计算的,而不是在变量被捕获时计算的:
int factor = 2;
Func<int, int> multiplier = n => n * factor;
factor = 10;
Console.WriteLine (multiplier (3)); // 30
其他回答
如果你有兴趣了解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);
}
}
基本上闭包是一段代码,你可以把它作为参数传递给函数。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# 7.0概要书中一个简单易懂的答案。
您应该知道的先决条件:lambda表达式可以引用方法的局部变量和参数 其中它被定义(外部变量)。
static void Main()
{
int factor = 2;
//Here factor is the variable that takes part in lambda expression.
Func<int, int> multiplier = n => n * factor;
Console.WriteLine (multiplier (3)); // 6
}
实部分:lambda表达式引用的外部变量称为捕获变量。捕获变量的lambda表达式称为闭包。
最后需要注意的一点:被捕获的变量是在委托实际调用时计算的,而不是在变量被捕获时计算的:
int factor = 2;
Func<int, int> multiplier = n => n * factor;
factor = 10;
Console.WriteLine (multiplier (3)); // 30
下面是我从JavaScript中类似的代码创建的c#人为示例:
public delegate T Iterator<T>() where T : class;
public Iterator<T> CreateIterator<T>(IList<T> x) where T : class
{
var i = 0;
return delegate { return (i < x.Count) ? x[i++] : null; };
}
所以,这里有一些代码,展示了如何使用上面的代码…
var iterator = CreateIterator(new string[3] { "Foo", "Bar", "Baz"});
// So, although CreateIterator() has been called and returned, the variable
// "i" within CreateIterator() will live on because of a closure created
// within that method, so that every time the anonymous delegate returned
// from it is called (by calling iterator()) it's value will increment.
string currentString;
currentString = iterator(); // currentString is now "Foo"
currentString = iterator(); // currentString is now "Bar"
currentString = iterator(); // currentString is now "Baz"
currentString = iterator(); // currentString is now null
希望这对大家有所帮助。
A closure aims to simplify functional thinking, and it allows the runtime to manage state, releasing extra complexity for the developer. A closure is a first-class function with free variables that are bound in the lexical environment. Behind these buzzwords hides a simple concept: closures are a more convenient way to give functions access to local state and to pass data into background operations. They are special functions that carry an implicit binding to all the nonlocal variables (also called free variables or up-values) referenced. Moreover, a closure allows a function to access one or more nonlocal variables even when invoked outside its immediate lexical scope, and the body of this special function can transport these free variables as a single entity, defined in its enclosing scope. More importantly, a closure encapsulates behavior and passes it around like any other object, granting access to the context in which the closure was created, reading, and updating these values.