In this article we'll cover the behaviors of variables to Reference Types. In Part I of my article on memory allocation in the .NET Framework, I covered the basics of the Heap and Stack functionality and where Variable Types and Reference Types are allocated as our program executes. We also covered the basic idea of what a Pointer is.
Types of Reference Types
Variables pointing to our reference types are typed. What's that mean?
If we have a Mammal and a Vegetable class as follows:
public class Mammal
{
public int Weight;
}
public class Vegetable
{
public int Weight;
}
And we make a new Mammal:
Mammal programmer = new Mammal();
Our "Programmer" variable expects to be pointing to a Mammal so we can not set our reference to anything other than a Mammal.
programmer = new Vegetable(); // CAN'T DO THIS!
We can't even force our Vegetable to be a Mammal.
programmer = (Mammal) new Vegetable(); // CAN'T DO THIS EITHER!
However, both Mammal and Vegetable inherit from System.Object so we CAN do this:
object programmer = new Mammal();
programmer = new Vegetable(); // CAN DO THIS!
A reference to a Mammal can also point to anything that is a Mammal, meaning anything that inherits from our Mammal class. So if we have a Human class as follows.
public class Human:Mammal
{
public int IQ;
}
We can do this:
Mammal programmer = new Mammal();
programmer = new Human(); // CAN DO THIS! HUMANS ARE MAMMALS.
But then can't reference the IQ property of our programmer variable because it's only pointing to a Mammal (even though this particular Mammal is a Programmer):
programmer.IQ = 5; // NOT AVAILABLE -- IT'S JUST A MAMMAL
To get to the IQ of our Human programmer, we have to be looking through a reference to a Human:
Mammal programmer = new Mammal();
programmer = new Human();
Human JohnDoe = programmer as Human;
JohnDoe.IQ = 5; // AVAILABLE -- IT'S A HUMAN
Even though this is a true statement:
programmer.Equals(JohnDoe)