C# 当一个变量关闭两次时,它存储在哪里?
我饶有兴趣地阅读了这篇文章,文章名为: 你看,C#编译器检测委托何时形成一个闭包,该闭包被传递出当前范围,并将委托和相关的局部变量提升到编译器生成的类中。这样,它只需要一些编译器技巧来传递编译器生成的类的实例,因此每次调用委托时,我们实际上是在调用该类上的方法 因此,本质上,一个封闭变量存储为匿名类的成员变量,该匿名类还包含表示lambda表达式的委托或在该变量上封闭的其他代码 如果是这种情况,当一个方法包含两个不同的lambda表达式,并且它们都引用相同的局部变量时,会发生什么情况C# 当一个变量关闭两次时,它存储在哪里?,c#,.net,lambda,closures,C#,.net,Lambda,Closures,我饶有兴趣地阅读了这篇文章,文章名为: 你看,C#编译器检测委托何时形成一个闭包,该闭包被传递出当前范围,并将委托和相关的局部变量提升到编译器生成的类中。这样,它只需要一些编译器技巧来传递编译器生成的类的实例,因此每次调用委托时,我们实际上是在调用该类上的方法 因此,本质上,一个封闭变量存储为匿名类的成员变量,该匿名类还包含表示lambda表达式的委托或在该变量上封闭的其他代码 如果是这种情况,当一个方法包含两个不同的lambda表达式,并且它们都引用相同的局部变量时,会发生什么情况 void
void Test(IList list)
{
int i = 0;
list.Any( a => { Console.WriteLine("Lambda one says: {0}", i++); return true;} )
.Any( a => { Console.WriteLine("Lambda two says: {0}", i++); return true;} );
}
我很确定我知道这里的行为。我的问题是,
i
到底存储在哪里?该方法只有一个闭包类,而不是每个匿名方法都有一个闭包类。一个类将有两个实例方法和一个字段。该字段将存储i
的值,这两个方法将分别对应于您的两个匿名方法。FWIW,该代码不会编译Any()
是IEnumerable
的一个扩展方法,需要Func
notAction
@Cameron,除非他们有自己的Console
类和返回布尔值的WriteLine
方法。(还有他们自己的Any
扩展方法,用于IList
,因为LINQAny
方法不接受IList
)。所有局部变量都存储在执行堆栈上。@jdweng这是完全错误的,这里显示的代码就是这样,它甚至包含了语言文档中的引号,解释了本地存储在哪里(以及它如何不在堆栈上)。如果变量需要存储在堆栈上,则闭包不可能工作,因为变量需要在方法完成后存在,如果变量存储在堆栈上,则闭包不可能工作。首先,内存必须在某个位置,局部变量必须放在堆栈上。其次,i不是lambda表达式的一部分,因此语言文档中的引用不适用。