c#events:如何访问变量

ren*_*ren 5 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)
    {
        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();
    }
}
Run Code Online (Sandbox Code Playgroud)

怎么ChangeViewEvent解雇的时候,事件处理程序仍然可以访问变量i?我的意思是不应该超出范围或什么?

jas*_*son 6

为什么当ChangeViewEvent被触发时,事件处理程序仍然能够访问变量i?我的意思是不应该超出范围或什么?

不,它是由lambda表达式捕获的.它被"提升"到编译器生成的类中,因此即使它"超出范围",它仍然可以被lambda表达式访问.(请记住,"超出范围"只是意味着"无法通过其简单名称访问".这并不意味着与该变量关联的存储空间已消失且其他任何人都无法访问.)

顺便说一句,这是一个在许多原因经常重复的谎言是"值类型住在堆栈上"是假的.在这种情况下,您有一个值类型实际上被提升到编译器生成的类中,最终生活在堆上.

有关此主题的更多信息,请参阅MSDN.