Value Types and Reference Types

To keep track of what is happening in a C# program, it is important to understand what value types and reference types are and the differences between them. You will also need to know when to create each type and why, which helps in creating well-designed, efficient, and maintainable code.

A reference type is a type that is allocated on the managed heap. The reason it is called a reference type is that the variables used in code point to, or refer to, the object on the heap. Copying one reference type variable to another will copy only the reference to the object, not the actual object on the heap. Changes to the value of a reference type object are visible through every reference variable that points to that object. C# has built-in reference types, such as arrays and strings, which will be discussed later in this chapter, in the sections "Arrays" and "String Formatting." You can also create your own reference types by declaring them as a class. There are many examples of how to create a class throughout this book.

Value types are allocated on the stack. They are named as such because they hold their actual value on the stack. When you copy one value type to another, the value is copied from one variable to the other. Changes to the value of a value type are isolated to the variable for that value type only. C# has built-in value types, such as int and float, which will be discussed in the next section. You can also create your own value types by declaring them as struct. The reason to create a new value type would be if the type acted like one of the built-in types and required value type semantics. Examples would be a complex number or matrix type.

Why value types and reference types? In other languages, built-in types, such as int and float, are often handled in a different way than objects. They are not really objects, so the developer must write special code and wrappers to make them behave properly in an object-oriented environment. In C#, many of the built-in types are value types, which allow them to be used in the same way that other objects are used. Also, because built-in types require special optimizations they must be handled by the system in a way that is efficient. Creating the concept of a value type enables C# to bring together the two goals of having object-oriented built-in types without sacrificing efficiency. By creating the concept of a value type, built-in types such as int and float may be worked with in a program the same as reference types, which are objects.

The C# language implements a concept known as Type System Unification, in which everything is considered an object. Because value types are ultimately derived from the object type (actually the hierarchy is value type > System.ValueType > System.Object), they can be used as objects anywhere in code. Other languages work around this by creating object wrappers for built-in types, but in C# this occurs automatically.

This automatic process of converting value types to objects is called boxing. Converting an object that has been boxed back to a value type variable is called unboxing. The benefits of this can be seen when working with an ArrayList, or other Base Class Library (BCL) collection classes, which accept only object types. Value types assigned to the collection are automatically boxed when added and unboxed when retrieved. Be aware that overhead is associated with boxing and unboxing. Type system unification through boxing and unboxing supports object-oriented development and makes the developer's job easier. The following snippet demonstrates boxing and unboxing:

 ArrayList myArrayList = new ArrayList(); int       myInteger   = 7; myArrayList.Add(myInteger);       // myInteger is boxed myInteger = (int)myArrayList[0];  // myInteger is unboxed 

The preceding code creates a new ArrayList collection and an int type. The ArrayList holds a list of reference types and the int holds a value type. When the myInteger is added to myArrayList, it is boxed, so that myArrayList can hold it as a reference type. The first call to Add on myArrayList puts the added element into position 0. Pulling the boxed int out of myArrayList requires that it be cast, with the (int) syntax, to its original value type.

All C# types ultimately inherit from the object type. Built-in reference types inherit directly from object. However, value types inherit from System.ValueType, which in turn inherits object. Figure 2.1 shows the inheritance relationship of value types and reference types.

Figure 2.1. Value and reference type inheritance.

graphics/02fig01.gif



C# Builder KickStart
C# Builder KickStart
ISBN: 672325896
EAN: N/A
Year: 2003
Pages: 165

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net