Say you have a button on your form. You attached an anonymous function to button's Click
event:
void Test()
{
int x = 10;
btn.Click += (sender, e) => { MessageBox.Show(x.ToString()); };
}
This works as expected and displays 10; means it can access local variables. My question is how and why? How does an anonymous function get access to the local context?
The actual problem I'm dealing with is that I need to upgrade (so to speak) this anonymous function to a regular function (event handler). But doing that means I'll lose access to the variable x. I can't pass it in as a parameter too because then I'll not be able to attach it to Click
event (signature mismatch). I can work around this by creating global variables and all that, but how do anonymous functions make it possible to access things that were outside their scope?
Half of the point of anonymous functions are that they can capture the context in which they're specified. It's extremely convenient to be able to do so - that's the "why" part.
The way the compiler does this is to create a new class in cases where it needs to. So your code would be converted to something like:
void Test()
{
TestHelper helper = new TestHelper();
helper.x = 10;
btn.Click += helper.Method;
}
private class TestHelper
{
public int x = 10;
public void Method(object sender, EventArgs e)
{
MessageBox.Show(x.ToString());
}
}
Every use of x
within Test
is converted into a use of helper.x
for the appropriate instance. This is how variables with different lifetimes is covered too. For example, suppose you had a loop like this:
for (int i = 0; i < 10; i++)
{
int x = i;
// Use with some anonymous function
}
then it would create a new instance of TestHelper
for each iteration of the loop... whereas if x
had been declared outside the loop, there'd just be a single instance that all the anonymous functions would effectively share.
When it's just this
that's captured, the compiler creates an instance method within the existing class instead of creating a helper class. When there are different scopes with potentially multiple anonymous functions which capture a variety of variables, things can get a lot more complicated, with some helper classes having references to instances of other helper classes, etc.
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