Are anonymous methods defined inline ? In the example below, the delegate object "d" is having reference of an anonymous method, which is accessing "x" variable which is defined in the Fun method. The scope of "x" should be limited to Fun method, but when we call MyFun, which invokes the delegate passed as parameter and increments the value of "x".
The output comes out to be "6", how does this happen ? How the value of "x", or in first place "x" variable itself was available in the anonymous method ?
public delegate void Del();
public void Fun()
{
int x = 5;
Del d = delegate { x++; };
MyFun(d);
Console.WriteLine(x);
}
public static void MyFun(Del d)
{
d();
}
Are anonymous methods defined inline?
I don't know what "inline" means.
In the example below, the delegate object "d" is having reference of an anonymous method, which is accessing "x" variable which is defined in the Del method.
No, x
is defined in the Fun
method. Del
is not a method, it's a delegate type.
The scope of "x" should be limited to Fun method.
Correct. Recall that "the scope of x" is defined as "the region of program text in which x may be looked up by its unqualified name". You are using the term correctly; the body of Fun
is the scope of x
. Note that the anonymous method is inside Fun
and therefore x
is in scope.
when we call MyFun, it invokes the delegate passed as parameter and increments the value of "x".
Correct.
The output comes out to be "6".
Correct.
how does this happen ?
The question is not entirely clear. It sounds like you've already provided an explanation for how this happens: the variable x
is in scope inside the anonymous function, the function increments the variable, so the value of the variable changes.
If your question is "what code does the compiler generate in order to make this happen?" the compiler pretends that you wrote something like:
public delegate void Del();
private class Locals
{
public int x;
public void AnonymousMethod() { x++; }
}
public void Fun()
{
Locals locals = new Locals();
locals.x = 5;
Del d = locals.AnonymousMethod;
MyFun(d);
Console.WriteLine(locals.x);
}
public static void MyFun(Del d)
{
d();
}
This is called Closure. It captures x
and uses it as soon as the delegate is executed. It's done through some compiler magic.
It can be confusing sometimes, though. For instance, if you change x
after defining the delegate, that change value would be used.