Mladen Prajdić Blog

Blog about stuff and things and stuff. Mostly about SQL server and .Net

When (int)x isn't the same as Convert.ToInt32(x)

Having started programming in c/c++ i've always been used to casting between types using () operator:

int i = (int)x

With the coming of .Net framework ValueTypes and ReferenceTypes were introduced and we started hearing about boxing and unboxing.

if you're not familiar with these terms pick a link from this search and read up.

Also we've been introduced to System.Convert class and IConvertible interface.

 

But old habits are hard to break and i've been preffering the (int) to Convert.ToInt32.

For all thing considered i've been treating them as equals. But i've been reminded that they're not with a nice little

error message saying Specified cast is not valid.

This is the shortened code i was running:

object o = (Int16)55; 
int convert1 = Convert.ToInt32(o); // ok
int convert2 = (int)o; // error

So why does this happen?

Well let's take it step by step.

1. 55 is Int32 by default as this line proves: 55.GetType().ToString()

2. By doing (Int16)55      we downcast the Int32 to Int16 since it's less than 32767 which is the max Int16 value

                                   no boxing yet since both Int32 and Int16 are ValueTypes

3. object o = (Int16)55;  boxes the Int16 into a System.Object thus making it a reference type

 

The thing about boxing and unboxing is that we have to know what type are we boxing and we must unbox it to the same type.

And when we have to explicitly unbox objects to their types. That's why we can't do simple

int convert2 = o;

 

And the difference between the two is:  


int convert2 = (int)o;

tries to directly cast the object to Int32 but since this violates the rule that unboxing must be done to the same type

which is Int16 in this case an above error is returned.


int convert1 = Convert.ToInt32(o); 

uses IConvertible interface to cast it. So it internaly unboxes the object o to Int16 and then directly casts the Int16 to Int32.

 

Isn't boxing and unboxing real "fun"? 

But it's nice of the .Net framework to remind us of such things every now an then...  :)


Legacy Comments


Jeff
2006-12-04
re: When (int)x isn't the same as Convert.ToInt32(x)
I think the key is this: Converting is not the same as Casting.

Converting performs a conversion -- it changes the VALUE returned (and often the type as well). Casting always returns the SAME value, but as a different type.

Jon
2006-12-06
re: When (int)x isn't the same as Convert.ToInt32(x)
Ahh when did you move onto C/C++...abandened good ol C# ehh...

int main() or void main() :)

That should cause another war !



Mladen
2006-12-07
re: When (int)x isn't the same as Convert.ToInt32(x)
I started with c/c++ and then moved to c# :)

i don't really care much about int main or void main.
It's not that big of a deal...

Jon
2006-12-08
re: When (int)x isn't the same as Convert.ToInt32(x)
I knew a guy think his name was richard heythafler or something like that...well he wrote the book Unleashed C...its quite an old book but have heard it was great. I used to once in a while joke with that guy about void main and boy would he get pissed. Total standards guy..cant mess with him especially when it came to C. Think he called himself Doc. C. :-)

Mladen
2006-12-08
re: When (int)x isn't the same as Convert.ToInt32(x)
It's the same as goodl old C# vs VB war :)
completly ridicolous.

Jon
2006-12-08
re: When (int)x isn't the same as Convert.ToInt32(x)
At devconnections they had a good presenter from MS who said stop the VB/C# wars
its not worth it. He then gave us stats as he was one of the project managers running the development of the programming tools at microsoft. He said instead of all these wars we need a new language say B# which didnt care whether you typed code in VB.net or C#..or a mixture, the result would be the same. And thats how close these languages run with each other. For heavens sakes convertors for both languages can be found on many random sites!

Annnnn
2008-09-17
re: When (int)x isn't the same as Convert.ToInt32(x)
dont understand a word

Tom Wilson
2009-08-03
re: When (int)x isn't the same as Convert.ToInt32(x)
Thanks for this article. I was getting Invalid Cast messages and didn't realize that casting handled unboxing differently than Convert().

Thanks!