Friday, August 29, 2008

.NET Primitive Wrapper Classes Where are thou?

In my day-to-day experience with code, forum users, other developers, i have been asked this question (Wrapper classes for primitive type) a thousand times before and now. Most developers especially the one's coming from Java Land (Like me, i am a Java Lander and still i am) seems to bring with them the Jar of Java coffee, and when they successfully arrive NLand, they realize its a different ball game here, because NPeople are not coffee drinkers, they are business men. Lets cut the story of N and J short, because the similarity and the dissimilarity of both lands is what makes them different.

We will not argue about the two lands today, but try to work around a simple primitive Wrapper for int, lets call our wrapper BigInteger or Integer (I will choose Integer or something like IntegerWrapper since .NET people may want to include Integer class as part of the base class libraries in the upcoming and not so far future. In Java, int is mutable because you are allowed to change the value of int anywhere in your code.

In Java we have several Wrapper classes which i will like to metion below, they wrap-up primitive data - types and have an object representation of it. The following class are some of the primitive wrapper classes in Java.

  1. BigDecimal
  2. BigInteger
  3. Byte
  4. Double
  5. Float
  6. Long
  7. Integer
  8. Short
All of these wrapper classes described above inherit from an abstract class called Number (You can sense some intuitiveness of java here). So in java, a primitive integer type can be used as follows :


int value = 200;
Integer bigInt = value;
value = bigInt;


Although wrapping and un-wrapping or autoboxing and unboxing (NLand calls it Boxing and UN-Boxing. But to object) primitive data types has a performance implications, but there are some situations that we cannot do without them. So how to we bring this type of functionality to .NET, how do we ensure that our primitive types can be treated as a reference type. First let me point out some few facts about what we have in the .NET API (Application Programming Interface).

Boxing and UNBoxing

Well, with the little approach we described above, we can fully understand that in .NET we have the term boxing and unboxing. This allows us to use an value type as an object and re-casting the value type from an object to its primitive state : The following is valid :


object value = 200; //Store an integer
int intValue = (int) value; //returns the value 200 to an int via type casting. It
is not automatic casting.


The above snippets shows how we can do boxing and unboxing in .NET, but where is the performance implications in this? of cos there is, when you cast a primitive type to object in .NET, an reference is allocated in the garbage-collected heap, that means an object memory is allocated for it. Let us take another simple approach :


object value = 200;
object value2 = value;

value2 = 500;
value still remains 200.


The code above retains the content of value and creates a new object in the memory heap when we assigned value to value2. We would have thought that the two objects would have a reference to a single object in memory, but the data is duplicated. So we need to be carefull when dealing with boxing amd unboxing this way.

Also we can use the System.ValueType class, which is the base class for all .NET value types, still this approach does not guarantee type safety and and it encourages more type casting and also incur the performance implications as the boxing and un-boxing approach.

So what are we going to do?

we are going to create a custom Integer Wrapper for .Net, and we will ensure that it is used like its java counterpart. So here our code goes :


public class Integer
{
int value = 0;

public Integer(int value)
{
this.value = value;
}

public static implicit operator Integer(int value)
{
return new Integer(value);
}

public static implicit operator int(Integer integer)
{
return integer.value;
}

public static int operator +(Integer one, Integer two)
{
return one.value + two.value;
}

public static Integer operator +(int one, Integer two)
{
return new Integer(one + two);
}

public static int operator -(Integer one, Integer two)
{
return one.value - two.value;
}

public static Integer operator -(int one, Integer two)
{
return new Integer(one - two);
}
}


The code above is a representation of the Integer wrapper class in java in .NET. So, having created our class above, we need to see how we can utilize it. Below is how we can make use of it.


Integer integer = 345;

integer = 10 * 11;

int value = integer;


Now we have our a reference type for integer type in .NET. Note, you can overload other operators to make sure your reference type can be used with other operators. Enjoy your Wrapper.

No comments: