9.8 All types are objects


As well as additional unsigned types and a new decimal type, there is another big difference between C# simple types and Java primitive types “ C# allows you to treat all types, including value types, as objects. In Java, primitive types are not objects, do not behave like objects, and cannot be treated like objects. If you need an object representation of a primitive type, the Java core library has the following wrapper java.lang classes which can be used in place of the primitives: Byte , Short , Integer , Long , Float , Double , Character , and Boolean .

All types in C# are ultimately objects derived from System.Object . The process whereby CLR converts a simple value type into an object is called boxing . Boxing bridges the gap between value types and reference types. It enables a unified view of the type system whereby a value of any type can be treated as an object.

9.8.1 Boxing

Boxing can be performed implicitly or explicitly. The following shows an example of explicit boxing. An int simple value type is being boxed when line 7 is executed.

 1: using System;  2:  3: public class Test{  4:  5:   public static void Main(string []args){  6:     int i = 99;  7:  object o  =  (object)i;  8:     Console.WriteLine(o.ToString());  9:     Console.WriteLine(o.GetType()); 10:   } 11: } 

Output:

 c:\expt>test 99 System.Int32 

ToString() and GetType() are methods of the System.Object ( object ) class, which return a string representation and type of the object respectively.

You can replace lines 7 “ 9 with the following statements:

 7:     // remove line 7 8:     Console.WriteLine(  i  .ToString()); 9:     Console.WriteLine(  i  .GetType()); 

The program compiles and, when executed, produces the same output. In this case, i has been implicitly boxed into an object type. Since all types (including int ) are subclasses of object , such implicit conversions are legal.

The code fragment below does not show boxing.

 // Test is a user-defined class. Test t = new Test(); object o = t; 

Boxing is different from converting or casting a reference type (such as Test in this example) to the object type. In this case, no new object is created. The same instance is used, and is simply regarded as a less derived object type. In the case of real boxing, a new object is created and a copy of the value type copied over to this new object .

9.8.2 Unboxing

The opposite of boxing, unboxing is the conversion from the object type to any value type. Unlike boxing, unboxing is usually explicit. During unboxing, the object instance that is being unboxed is first checked to see if its original type matches the target value type. Unboxing an object to a wrong value type, or attempting to unbox a null , results in a System.InvalidCastException . The following code fragment shows an int being boxed and unboxed explicitly:

 int i = 99; object boxed = (object)i; // boxing int j = (int)boxed; // unboxing 

The following gives an InvalidCastException during runtime because the original type of the boxed object does not match a short .

 int i = 99; object boxed = (object)i; // boxing short j = (short)boxed; // InvalidCastException 

Even if you are trying to cast a boxed up int into a double , or something 'wider' in range, you will still get the exception:

 int i = 99; object boxed = (object)i; // boxing  double  j =  (double)  boxed; // InvalidCastException 

In this case, you need to obtain the initial int value first, and then perform a cast of the int into your desired simple type.

9.8.3 Why the boxing and unboxing?

At this point, you could (and should) be wondering what the purpose of the boxing mechanism is. It might seem better just to make all value types “ including the simple types int , long , float , and so on “ real object types.

Efficiency is the reason. It is definitely an advantage for all simple types to be objects. Objects come with all the goodness of OO technology “ for one thing, you can invoke methods on object types, something you cannot do with Java primitives. However, one big performance issue to consider is that object creation is naturally expensive.

In Java, primitive operations (such as the declaration, assignment, and addition of two int primitive types) are performed totally on the stack. No object is created on the heap if all you want to do is to perform a simple arithmetic addition of two numbers (which translates to no overheads corresponding to object creation). Subsequently the garbage collector will also not need to reclaim anything since no object has been created in the first place.

You can perform the same addition by creating two java.lang.Integer objects which encapsulate the two int values. The difference is that not only is the latter technique more expensive, it will also be slower because instead of working on the stack, the objects are created and manipulated on the heap. Worse still, you do not even need to take advantage of the OO features of the Integer class in this case. You have to live with the overheads of object creation, without even requiring the benefits it brings .

C# wants you to have the best of both worlds “ the ability to treat even simple types like objects, and yet avoid the overheads of object creation and destruction unless absolutely necessary.

When simple types are declared and assigned values in C#, no object is created and things are performed quickly on the stack. Only when the type is explicitly boxed, or if a method operation is applied on it (thus causing implicit boxing), will a real object be created on the heap and the value copied over to this object (see Figure 9.3).

Figure 9.3. Only when a value type is boxed is an object created on the heap, and the value copied over. Object creation is expensive and should be avoided if not necessary.

graphics/09fig03.gif

That's how C# gives you the best of both worlds and, best of all, everything is done transparently without the developer's intervention.



From Java to C#. A Developers Guide
From Java to C#: A Developers Guide
ISBN: 0321136225
EAN: 2147483647
Year: 2003
Pages: 221
Authors: Heng Ngee Mok

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