A: 

Structures are value types and allocated on the stack when used for local variables. But if you cast a local variable to Object or an interface, the value is boxed and allocated on the heap.

In consequence structures are freed after they fall out of scope besides they are boxed and moved to the heap after that the garbage collector becomes responsible for freeing them when there is no longer any reference to the object.

I am not sure about the reason for all the compiler generated local variables but I assume they are used because you use object initializers. The objects are first initialized using a compiler generated local variable and only after complete execution of the object initializers copied to your local variable. This insures that you will never see an instance with only some of the object initializers executed.

Daniel Brückner
Value types are not guaranteed to be allocated on the stack. See [the stack is an implementation detail](http://blogs.msdn.com/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx).
Aaronaught
Would it then be generally correct to say that the boxing and unboxing operations are fundamentally nothing else than moving value-type values between the stack and the heap?
stakx
@stakx: **NO**, that is completely *incorrect*. Boxing a value type allows it to be passed around as a reference type so that copies of the object aren't made every time an assignment happens. The relationship to the stack and heap is **not your concern** as a programmer and the spec does **not make guarantees**.
Aaronaught
Of course it is only an implementation detail but the answer to the question depends on this implementation detail.
Daniel Brückner
*@Aaronaught:* That's a great blog post that you've linked to. I see now that my question in the comment above would have been unnecessary had I first read that blog entry. Thanks for the clarification!
stakx
If you only look at the CLI specification you will not get an answer - the specification is intentionally vague in order to not impose any constraints on the implementation.
Daniel Brückner
*@Aaronaught* again: I think you'd deserve the mark for answering this question (if you happened to re-post as an answer what you've already said above).
stakx
+5  A: 

Please consider the following:

  1. The difference between value types and reference types is primarily one of assignment semantics. Value types are copied on assignment - for a struct, that means copying the contents of all fields. Reference types only copy the reference, not the data. The stack is an implementation detail. The CLI spec promises nothing about where an object is allocated, and it's a bad idea to depend on behaviour that isn't in the spec.

  2. Temporary objects (locals) will live in the GC generation 0. The GC is already smart enough to free them as soon as they go out of scope. You do not need to switch to struct instances for this.

  3. Mutable value types already have a tendency to lead to bugs because it's hard to understand when you're mutating a copy vs. the original. But introducing reference properties on those value types, as would be the case with a fluent interface, is going to to be a mess, because it will appear that some parts of the struct are getting copied but others aren't (i.e. nested properties of reference properties). I can't recommend against this practice strongly enough, it's liable to lead to all kinds of maintenance headaches in the long haul.

  4. The g_initLocal0 and related fields are there because you are using object initializers. Switch to parameterized constructors and you'll see those disappear.

Value types are typically allocated on the stack, and reference types are typically allocated on the heap, but that is not actually part of the .NET specification and is not guaranteed (in the linked post, Eric even points out some obvious exceptions).

Instead, trust the GC to deal efficiently with temporary data, especially local variables; it almost always does.

Aaronaught
+2  A: 

It is a JIT compiler implementation detail where it will allocate the .locals. Right now, I don't know any that doesn't allocate them on a stack frame. They are "allocated" by adjusting the stack pointer and "freed" by resetting it back. Very fast, hard to improve. But who knows, 20 years from now we might all be running machines with CPU cores that are optimized to run only managed code with a completely different internal implementation. Probably cores with a ton of registers, the JIT optimizer already uses registers to store locals now.

The temporaries are emitted by the C# compiler to provide some minimum consistency guarantees in case object initializers throw exceptions. It prevents your code from ever seeing a partially initialized object in a catch or finally block. Also used in the using and lock statements, it prevents the wrong object from being disposed or unlocked if you replace the object reference in your code.

Hans Passant