Reputation: 884
I'm refreshing my memory on how reference and value types work in .NET. I understand that the entry on the stack for a reference type contains a pointer to a memory location on the heap. What I can't seem to find details about is what else the stack entry contains. So, given the following:
Customer customer;
customer = new Customer();
After the first line of code an entry on the stack containing a null pointer will exist. Does that entry also contain the identifying name "customer"? Does it contain type information?
Have I fundamentally misunderstood something?
Upvotes: 6
Views: 534
Reputation: 941605
Only the pointer to the object is stored, nothing else. Not on the stack, it is stored in a processor register. Only if the method is large and the register is better used for other purposes will it be stored on the stack. Making that the decision is the job of the optimizer. Which is in general fairly unlikely to happen since you'll probably be using properties and methods of the Customer class so keeping the pointer in a register is efficient.
This is otherwise the basic reason why a NullReferenceException can tell you nothing useful about what reference is null. Associating the pointer value back to a named "customer" variable can only be done by a debugger. It needs the PDB file to know the name of the variable, that name is not present in the metadata of the assembly. Which is the basic reason why you cannot use Reflection to discover local variable names and values.
And this is also why debugging only works well when you use it on the Debug build of your project. That disables the optimizer and gets the pointer value to always be stored back to a stack slot, allowing the debugger to reliably read it back. At a significant cost, the basic reason you should only ever deploy the Release build of your project.
Upvotes: 11
Reputation: 30032
1- Variable names are not stored in memory along with the reference.
2- A null
reference doesn't store the type of the object.
string str = null;
if(str is String)
{
Console.WriteLine("I'm a string");
}
else
{
Console.WriteLine("I'm not a string");
}
// This will print: "I'm not a string"
You're actually telling the compiler, allow me to create only string references using the mapped storage location by str
.
Variables represent storage locations. Every variable has a type that determines what values can be stored in the variable
Upvotes: 2
Reputation: 764
The variable name customer
does only exist in the source code (as it is of no interest to your computer). During runtime, nobody knows how the variable was called in the code.
Jon Skeet wrote a good article about what is stored on the heap and what goes to the stack. The first paragraph (what's in a variable?) should answer your question:
The value of a reference type variable is always either a reference or null. If it's a reference, it must be a reference to an object which is compatible with the type of the variable. For instance, a variable declared as
Stream s
will always have a value which is either null or a reference to an instance of theStream
class. (Note that an instance of a subclass ofStream
, egFileStream
, is also an instance ofStream
.) The slot of memory associated with the variable is just the size of a reference, however big the actual object it refers to might be. (On the 32-bit version of .NET, for instance, a reference type variable's slot is always just 4 bytes.)
Upvotes: 2