The difference between reference types and value types is often confusing for beginners due to not understanding what a variable of value type actually holds. We know that:
Is it possible to inspect each kind of variable to either see the value, or the actual reference itself? Is the reference stored as some kind of coded value? I know that references can be passed by value so I'm assuming so.
I think this would help newcomers with their understanding, and be very interesting to explore.
A reference type refers to an object in some external memory space. This is in contrast to value types, that are stored where they are created. Experts also talk about reference types as being 'dynamically allocated.
Reference Types are used by a reference which holds a reference (address) to the object but not the object itself. Because reference types represent the address of the variable rather than the data itself, assigning a reference variable to another doesn't copy the data.
There are two kinds of types in Visual Basic: reference types and value types. Variables of reference types store references to their data (objects), while variables of value types directly contain their data.
Structs are value types, while classes are reference types, and the runtime deals with the two in different ways. When a value-type instance is created, a single space in memory is allocated to store the value. Primitive types such as int, float, bool and char are also value types, and work in the same way.
Is it possible to inspect each kind of variable to either see the value, or the actual reference itself?
Just to clarify, the value of a variable of reference type is a reference. The reference is the value.
A reference is a kind of value, just like an int is a kind of value. Unlike an int, a reference is a value that can only be copied and dereferenced; you cannot observe its value directly in C#, because its value is an implementation detail of the garbage collector.
Is the reference stored as some kind of coded value?
Yes, exactly. In practice, a reference is a 32 or 64 bit integer (depending on whether you are in a 32 or 64 bit process) that is a pointer to some structure known to the garbage collector as being associated with the data of the referred-to object.
If you want to look at references directly, the tool to do so is the debugger. Load your C# code into the debugger, compile it, run it, hit a breakpoint, and take a look at the state of the stack and registers. With a little cleverness you should be able to figure out which stack locations and registers correspond to which local variables. The locations corresponding to local variables of value type will contain the values; those of reference type will contain values that look like pointers. If you examine those pointers in the memory window, you will then be looking at the structures maintained by the garbage collector that describe the contents of the object.
This is probably one for Jon Skeet, but I might have a different angle on it:
Don't worry too much about how these things are represented in memory. Unless you have read through the whole language specification - who does that anyway? - you don't really need to know. Really. Don't bother memorizing what data is stored where - chances are, that this is implementation specific.
Instead, think in terms of semantics, e.g. that a value type passed to a function is copied, whereas a reference type is referenced. Stuff like that.
You don't really want to know what a declaration of a type actually holds. Believe me. What you want to know, is how it behaves.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With