c#事件:如何访问变量
假设c#事件:如何访问变量,c#,events,scope,C#,Events,Scope,假设 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) {
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
?我是说它不应该超出范围吗
为什么在触发ChangeViewEvent时,事件处理程序仍然能够访问变量i?我是说它不应该超出范围吗
不,它是由lambda表达式捕获的。它被“提升”到编译器生成的类中,以便lambda表达式仍然可以访问它,即使它“超出范围”。(请记住,“超出范围”仅表示“无法通过其简单名称访问”。这并不意味着与该变量相关联的存储空间消失,任何其他人都无法访问。)
顺便说一句,这是为什么“值类型存在于堆栈上”这个经常被重复的错误是错误的原因之一。在本例中,您有一个值类型,它实际上被提升到编译器生成的类中,并最终存在于堆中
有关此主题的更多信息,请参阅。它被称为捕获变量
这的确是个很好的问题!:)