Data Types and Boxing
After our introduction to C#, we continue with an additional topic that's important to most programmers: managing data types.
Value Types and Reference Types
C# provides both value types and reference types. The difference between them is a fundamental concept. In strictly object-oriented languages, every variable is an object. In contrast to variables you might know from procedural languages, objects are far more complex and lead to some overhead. When somebody allocates an integer variable in C/C++, 4 bytes are allocated on the stack. But when an instance of an object is created, far more memory is needed to store all the administrative information.
To raise performance, C# defines a difference between variables storing data (value types) and objects that can be used to store data as well (reference types). References are similar to references in C++. Therefore, references are extremely important because it isn't necessary to pass an entire object to a method. We'll get back to this major difference later in this book.
Boxing
The question now is how the difference between value types and reference types can be used efficiently. One potential scenario is boxing. With the help of boxing, it's possible to hide a variable inside an object.
The following example shows how this works:
using System; public class Demo { public static void Main() { int a = 42; object b = a; int c = (int) b; Console.WriteLine("c: " + c); } }
First, we create an integer variable. After that, the variable is hidden inside an object. To extract the data from the object, we perform a cast, which means that we modify the data type of the variable. This can be done by putting the desired data type in brackets. In the following code, you can see the result we can expect:
[hs@duron csharp]$ mono box.exe c: 42
With regard to reference types, many programmers get the wrong impression of what they're dealing with. Using a reference type is not the same as using a pointer in C or C++. To make this clear, we've decided to include an example showing that the situation is very different from C:
using System; public class Demo { public static void Main() { int a = 42; object b = a; Console.WriteLine("before: " + a); Increment(b); int c = (int) b; Console.WriteLine("after: " + c); } static void Increment(Object x) { int y = (int)x; y++; x = y; } }
After creating an integer variable, we put it into an object. It is passed to the Increment function. As we just saw, objects are reference types. Inside the function, we take the object and increment its content by one. Finally, the new value is assigned to the object. If we had a pointer (as in C), the result would differ from the one that follows:
[hs@duron csharp]$ mono box.exe before: 42 after: 42
Both values are the same. The reason for that is that we do not access the variable in the Main function of the program. This is an important concept, and you have to take care to understand it.