This article describes what type-unification is. It also discusses about boxing and un-boxing, and compares what is done in Java (1.4) where not everything is an object.
Those working in Java would know about what are known as primitive and composite data-types. For those who've never worked with Java, here's a brief overview of the same and related.
Object oriented programming has three pillars - encapsulation, inheritance and polymorphism. C++ has them all. They are implemented by what are known as classes.
In C++, you have classes, you can have methods and fields within classes (allowing encapsulation and inheritance) and you can override the methods (polymorphism). And you can have global methods and variables.
In Java, you have classes with almost all the features as in C++ but you do not have anything global. Everything has to be within a class. All classes ultimately derive from what is known as "Object".
But not everything is an object. Data-types like char, long, short etc are not classes but what are known as primitive data-types, which are always passed by value. All classes are known as composite data-types and are always passed by reference.
Primitive data-types are excellent performance-wise. Creating an object using "new" is not very efficient as all objects are placed on heap. Heap management is costlier than stack management, more so for simple objects (like long, char etc use minimal memory). Primitive types are used to create automatic variables and put them on stack (in-line).
These data-types are not derived from "Object" and hence, unusable by collections like ArrayList, Hashtable etc. However, they do have "wrapper" classes (in java.lang package) as given below:
|
Primitive Type
|
Wrapper Class
|
Primitive Type
|
Wrapper Class
|
|
byte
|
Byte
|
char
|
Character
|
|
short
|
Short
|
int
|
Integer
|
|
long
|
Long
|
float
|
Float
|
|
double
|
Double
|
void
|
Void
|
As such, if you need to use a "long" in a collection, you need to wrap it:
[Java]
long l = 10;
Long longObject = new
Long(long); // Wrap
Long longValue =
longObject.longValue(); // Un-wrap
In C# (and Java 1.5), everything is an "Object", be they primitive-type or composite-type.
In C#, the so-called primitive types of Java are implemented as what are known as value-types, meaning that they would be passed by value and not be reference.
In addition to classes (which are always reference-types), C# has structures and enumerations which are always passed by values. The primitive-types of Java have been implemented as structures in .Net, which are always created on-heap/in-line. These data-types are available directly through simple keywords in C#.
|
Java-Type
|
C# Keyword
|
.Net-Type (Structures)
|
|
byte
|
byte
|
System.Byte
|
|
short
|
short
|
System.Int16
|
|
int
|
int
|
System.Int32
|
|
long
|
long
|
System.Int64
|
|
float
|
float
|
System.Single
|
|
double
|
double
|
System.Double
|
|
char
|
char
|
System.Char
|
|
boolean
|
bool
|
System.Boolean
|
|
unsigned short
|
ushort
|
UInt16
|
|
unsigned int
|
uint
|
UInt32
|
|
unsigned long
|
ulong
|
UInt64
|
At the byte-code level, these types are classes derived from special class System.ValueType. You cannot explicitly derive your class from this class.
A structure is directly derived from this abstract class while enumerations are derived from another special (abstract) class System.Enum which in-turn derives from System.ValueType.
The screenshots on the next page demonstrate the same.
Actual code:

Disassembled view of the assembly:

Disassembled view of the System.Enum class:

Disassembled view of the System.ValueType class:

This brings us to what is known as Type-Unification: each data-type is derived from “Object”, be it value-type or reference-type.
The process of conversion of a value-type to a reference-type is known as boxing. The reverse of this is known as un-boxing. Boxing is an automatic process while un-boxing requires explicit type-casting.
[C#]
int x = 10;
object o = x; //Auto-Boxing
int y = (int)o; //Un-boxing, explicit type-casting
It has a strong advantage
that one can pass a "short" to any method that accepts "Object" as the parameter without a need for wrapping.
It is important to note that both boxing and un-boxing, like wrapping and unwrapping, are costly processes.
During boxing, memory is allocated on heap. The value is copied onto the heap and the reference is provided. During un-boxing, using the reference, the value is extracted from the heap and copied to the variable on stack.
Note that Java 1.5 has taken the path of .Net and introduced type-unification, boxing and un-boxing.