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?
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With