Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c# events: how variables are accessed

Tags:

scope

c#

events

Suppose

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();
    }
}

How come when ChangeViewEvent is fired, event handler is still able to access variable i? I mean shouldn't it be out of scope or something?

like image 725
ren Avatar asked Apr 05 '12 16:04

ren


2 Answers

How come when ChangeViewEvent is fired, event handler is still able to access variable i? I mean shouldn't it be out of scope or something?

No, it's captured by the lambda expression. It gets "lifted" into a compiler-generated class so that it's still accessible to the lambda expression even when it's "out of scope." (Remember, "out of scope" just means "not accessible by its simple name." It doesn't mean that the storage space associated with that variable is gone and not accessible by anyone else.)

By the way, this is one reason among many why the oft-repeated falsehood that "value types live on the stack" is false. In this case, you have a value type that is actually hoisted into a compiler-generated class and ends up living on the heap.

For more on this topic, see MSDN.

like image 71
jason Avatar answered Oct 21 '22 12:10

jason


It's called a captured variable.

http://en.wikipedia.org/wiki/Closure_%28computer_science%29#Delegates_.28C.23.2C_D.29

http://blogs.msdn.com/b/ericlippert/archive/2003/09/17/what-are-closures.aspx

like image 21
GregC Avatar answered Oct 21 '22 11:10

GregC