Familiarizing with value and reference types in C#

✓ Value types – Most of the primitive types, such as int, float, double, and char are collectively called value types. These types have a fixed size, and when you declare a variable, the compiler generates code that allocates a block of memory big enough to hold a corresponding value.

int i = 42;
int copyi = i;
i++; // i now contains 43, but copyi still contains 42

In abvoe example, even though copyi and i happen to hold the same value, there are two blocks of memory containing the value 42: one block for i and the other block for copyi. If you modify the value of i, the value of copyi does not change.

✓ Reference types – A class is a reference type. It is allot a small piece of memory that can potentially hold the address of (or a reference to) variable. The memory for the actual object is allocated only when the new keyword is used to create the object.

Circle c = new Circle(42);
Circle refc = c;

When you declare c as a Circle, c can refer to a Circle object; the actual value held by c is the address of a Circle object in memory. If you declare an additional variable named refc and you assign c to refc, refc will have a copy of the same address as c; in other words, there is only one Circle object, and both refc and c now refer to it.

✓ Using ref and out parameters
When you pass an argument to a method, the corresponding parameter is initialized with a copy of the argument. This is true regardless of whether the parameter is a value type (such as an int), a nullable type (such as int?), or a reference type (such as a WrappedInt).

In this example, the doIncrement method increments a copy of the argument (arg) and not the original argument, as demonstrated here:

static void doIncrement(int param)
{
    param++;
}
static void Main()
{
    int arg = 42;
    doIncrement(arg);
    Console.WriteLine(arg); // writes 42, not 43
}

✓ Creating ref parameters – When using a ref parameter, anything you do to the parameter you also do to the original argument because the parameter and the argument both reference the same data

static void doIncrement(ref int param) // using ref
{
    param++;
}
static void Main()
{
    int arg = 42;
    doIncrement(ref arg); // using ref
    Console.WriteLine(arg); // writes 43
}

Above example, the doIncrement method receives a reference to the original argument rather than a copy, so any changes the method makes by using this reference actually change the original value. That’s why the value 43 is displayed on the console.

✓ Creating out parameters – The compiler checks whether a ref parameter has been assigned a value before calling the method. However, there might be times when you want the method itself to initialize the parameter. You can do this with the out keyword.

static void doInitialize(out int param)
{
    param = 42;
}
static void Main()
{
    int arg; // not initialized
    doInitialize(out arg); // legal
    Console.WriteLine(arg); // writes 42
}

✓ Computer memory – C# divide the memory used for holding data in two separate areas, each of which is managed in a distinct manner. These two areas of memory are traditionally called the stack and the heap.

All value types are created on the stack. All reference types (objects) are cre-ated on the heap (although the reference itself is on the stack). Nullable types are actually reference types, and they are created on the heap.

✓ Stack – Stack memory is organized like a stack of boxes piled on top of one another. When a method is called, each parameter is put in a box that is placed on top of the stack. Each local variable is likewise assigned a box, and these are placed on top of the boxes already on the stack. When a method finishes, you can think of the boxes being removed from the stack.

✓ Heap – Heap memory is like a large pile of boxes strewn around a room rather than stacked neatly on top of each other. Each box has a label indicating whether it is in use. When a new object is created, the runtime searches for an empty box and allocates it to the object. The reference to the object is stored in a local variable on the stack. The runtime keeps track of the number of references to each box. When the last reference disappears, the runtime marks the box as not in use, and at some point in the future it will empty the box and make it available for reuse.

One of the most important reference types in the .NET Framework is the Object class in the System namespace.

Circle c;
c = new Circle(42);
object o;
o = c;

✓ Boxing – We show variables of type object can refer to any item of any reference type. However, variables of type object can also refer to a value type.

int i = 42;
object o = i;

boxing
If you modify the original value of the variable i, the value on the heap referenced through o will not change. Likewise, if you modify the value on the heap, the original value of the variable will not change.

✓ Unboxing – To obtain the value of the boxed copy, you must use what is known as a cast. This is an operation that checks whether it is safe to convert an item of one type to another before it actually makes the copy.

int i = 42;
object o = i; // boxes
i = (int)o; // compiles okay

unboxing

Circle c = new Circle(42);
object o = c; // doesn't box because Circle is a reference variable
int i = (int)o; // compiles okay but throws an exception at run time

✓ is operator – You can use the is operator to verify that the type of an object is what you expect it to be, like this:

WrappedInt wi = new WrappedInt();
object o = wi;
if (o is WrappedInt)
{
    WrappedInt temp = (WrappedInt)o; // This is safe; o is a WrappedInt
}

✓ as operator – The as operator fulfills a similar role to is but in a slightly truncated manner. You use the as operator as follows,

WrappedInt wi = new WrappedInt();
object o = wi;
WrappedInt temp = o as WrappedInt;
if (temp != null)
{
    ... // Cast was successful
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s