I was under the impression that lambda expression contexts in C# contain references to the variables of the parent function scope that are used in them. Consider:
public class Test
{
private static System.Action<int> del;
public static void test(){
int i = 100500;
del = a => System.Console.WriteLine("param = {0}, i = {1}", a, i);
del(1);
i = 10;
del(1);
}
public static void Main()
{
test();
}
}
outputs
param = 1, i = 100500
param = 1, i = 10
However, if this was true, the following would be illegal, because the lambda context would reference a local variable that went out of scope:
public class Test
{
private static System.Action<int> del;
public static void test(){
int i = 100500;
del = a => System.Console.WriteLine("param = {0}, i = {1}", a, i);
}
public static void Main()
{
test();
del(1);
}
}
However, this compiles, runs and outputs
param = 1, i = 100500
Which means that either something weird is going on, or the context keeps values of the local variables, not references to them. But if this was true, it would have to update them on every lambda invokation, and I don't see how that would work when the original variables go out of scope. Also, it seems that this could incur an overhead when dealing with large value types.
I know that, for example, in C++, this is UB (confirmed in answer to this question).
The question is, is this well-defined behaviour in C#? (I think C# does have some UB, or at least some IB, right?)
If it is well-defined, how and why does this actually work? (implementation logic would be interesting)