The "stack" and "heap" are implementation details, and not as important as the observable characteristics of value and reference types:
The Stack Is An Implementation Detail, Part One – Fabulous Adventures In Coding[
^]
The Stack Is An Implementation Detail, Part Two – Fabulous Adventures In Coding[
^]
But the terms can still be useful when thinking about how the types behave.
I think it would be more correct to say that the data for a value type is stored
inline, whereas the data for a reference type is stored
elsewhere (on the heap), with the
address of that data being stored inline.
So, given a reference type containing two fields:
class Foo
{
int x = 42;
string s = "Bar";
}
and an instance of that type:
Foo f = new Foo();
f
stores the address of the data for that instance - eg:
0x1234567
. That data might look something like:
0x1234567: 0
0x1234568: 0
0x1234569: 0
0x1234570: 42
0x1234571: 11
0x1234572: 173
0x1234573: 240
0x1234574: 13
The data for
i
is stored inline:
42
. But the data for
s
is stored
somewhere else, at address
0x0BADF00D
:
0x0BADF009: 0
0x0BADF00A: 0
0x0BADF00B: 0
0x0BADF00C: 3
0x0BADF00D: 66
0x0BADF00E: 97
0x0BADF00F: 114
Of course, this ignores
the concept of "boxed" value types[
^], which are stored in the same way as reference types.
Some more light reading: :)
The Truth About Value Types – Fabulous Adventures In Coding[
^]
Debunking another myth about value types – Fabulous Adventures In Coding[
^]
Six important .NET concepts: Stack, heap, value types, reference types, boxing, and unboxing[
^]