When I read next book of chapter \"Value and reference types\" then a question comes to my mind: \"When are value types stored in stack\"? Cause programmer cannot initialise
Well, firstly it is very rare that you would need to know, but basically, value-types are stored where-ever they are owned.
They are stored on the stack when they are part of the execution flow of a thread, which can mean:
ref
or out
) are simply a special-case of thisThey are stored on the heap (as part of an object) when:
object
, dynamic
, Enum
, ValueType
(yes: ValueType
is a reference-type; fun, eh?), ISomeInterface
, etc)The first web search hit on your question gives you Eric Lippert's The Truth About Value Types, which starts with the most important part: it is almost always irrelevant. So, why do you want to know? Will you program differently?
Anyway:
The truth is: the choice of allocation mechanism has to do only with the known required lifetime of the storage.
Another source of confusion appears to be that you assume reference and value types are 2 types of classes, that is not true
keyword class
-> Reference type
keyword struct
-> Value type
My question is: when are value types stored in stack?
From The Truth About Value Types:
[I]in the Microsoft implementation of C# on the desktop CLR, value types are stored on the stack when the value is a local variable or temporary that is not a closed-over local variable of a lambda or anonymous method, and the method body is not an iterator block, and the jitter chooses to not enregister the value
To be precise, the stack and the heap are (or should be) irrelevant in managed environments.
In practice, local variables value types (structs in C#) tend to be allocated on the stack. However, there are cases when they are allocated on the heap instead.
One such case is when they are boxed. Boxing means using an Int32
as an Object
, for example by passing it to a method that takes an object
parameter. One reason for this is polymorphism: Structs don't carry a vTable pointer and thus cannot do dynamic virtual method resolution (for such methods as ToString()
, for example) - but they are sealed, so they can do the resolution statically. On the other hand, if a struct is forced to be stored in an object
reference, it needs to be transformed to a heap-allocated vTable-enabled object.
A value type may also be allocated in the heap when it's part of a heap-allocated object - for example, when it's a data member (field) of a class.