Ah, you have discovered the magic of closures!
You are correct in thinking that "x" is a value type and that it should not behave in this way; that is if you weren't declaring an anonymous function inside of your method. An anonymous method is a closure and is bound to its parenting method body and the local variables in it (In this case it is the local variable "x" and the parenting method GetSomeHandler).
The important distinction is that it is bound to variables, not to values. In other words, the value of "x" is not copied in when "a" is declared. Instead, a "reference" to "x" is used so that "a" will always use the most recent value of "x". In fact, this "reference" to "x" will be persisted even if "x" goes out of scope. When you compile your program the compiler then works some of its "compiler magic" and generates something similar to the following snippet of code:
delegate void SomeHandler();
// This is the helper class generated by the compiler that allows an anonymous function inside your method access to local variables even after the function or method has returned.
sealed class SomeHandlerClosure
{
public int x;
public void CompilerNamedMethod()
{
Console.WriteLine(x);
}
}
static SomeHandler GetSomeHandler()
{
SomeHandlerClosure closure = new SomeHandlerClosure();
closure.x = 1;
SomeHandler a = new SomeHandler(closure.CompilerNamedMethod);
closure.x = 2;
return a;
}
static void Main(string[] args)
{
SomeHandler a = GetSomeHandler();
a();
}
The "GetSomeHandler" method is really where the magic happens:
1.At the beginning of method, an instance of the "SomeClosure" class is created. (Note that I chose to use the names "SomeHandlerClosure" and "CompilerNamedMethod" for clarity. In reality, the compiler generates names to prevent name collision.)
2.All references to the local variable "x" in the "GetSomeHandler" method have been replaced with references to the "x" field on the "SomeHandlerClosure" instance.
3.The delegate "a" is now assigned to a new delegate instance for "CompilerNamedMethod" on the "SomeHandlerClosure" instance.
Clear as mud??