Sunday, August 22, 2010

Casting and Unboxing in .NET

Recently I faced with an interesting behavior of casting in .NET. If you declare something as an object and then assign some value to it (for example System.Int32), and then try to cast this declared variable to other value type (like System.Int64), it doesn’t work. See the code bellow:
int intNumber1 = 100;
object intNumber2 = 100;
bool areNumbersOfTheSameType = intNumber1.GetType() ==
                               intNumber2.GetType(); // TRUE
bool areEqual = intNumber1.Equals(intNumber2); // TRUE

long longNumber1 = (long) intNumber1; // OK
long longNumber2 = (long) intNumber2; // InvalidCastException. Why?
The most confusing part here is that GetType() returns System.Int32 for both variables, and Equals() returns True, which means that these two variables are identical from any point of view. I was confused and started looking for an answer (on StackOverflow and looking through corresponding chapter in CLR via C# 3d edition).
Finally I was pointed to a good article on the topic written by Eric Lippert. The answer is very simple - I mixed up unboxing and casting operations.  The last row performs unboxing operation and tries to get System.Int64 value from the object while it actually contains System.Int32  value, and this is wrong. In order to make it work I need: first unbox System.Int32  from the object ant then cast it to System.Int64 value:
long longNumber2 = (long) (int) intNumber2; // Works fine!

No comments: