假设
public class Program
{
public static void Main(string[] args)
{
Program p = new Program();
A a = new A();
p.Do(a);
System.Threading.Thread.Sleep(1000);
a.Fire();
}
public void Do(A a)
{
int i = 5;
a.ChangeViewEvent += () =>
{
Console.WriteLine(i);
};
}
}
public class A
{
public delegate void ChangeView();
public event ChangeView ChangeViewEvent;
public void Fire()
{
if(ChangeViewEvent != null)
ChangeViewEvent();
}
}
如果触发ChangeViewEvent
,事件处理程序仍然能够访问变量i
?我的意思是不应该超出范围或什么?
答案 0 :(得分:6)
为什么在触发ChangeViewEvent时,事件处理程序仍能访问变量i?我的意思是不应该超出范围或什么?
不,它是由lambda表达式捕获的。它被“提升”到编译器生成的类中,因此即使它“超出范围”,它仍然可以被lambda表达式访问。 (请记住,“超出范围”仅仅意味着“无法通过其简单名称访问。”并不意味着与该变量关联的存储空间已消失且其他任何人都无法访问。)
顺便说一下,这是一个的原因,其中很多原因是“值类型存在于堆栈中”的经常重复的错误是错误的。在这种情况下,您有一个实际被提升到编译器生成的类中的值类型,最终生活在堆上。
有关此主题的更多信息,请参阅MSDN。
答案 1 :(得分:4)