Click here to Skip to main content
15,886,689 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
C#
Int32 i = 1;
UInt32 u = (UInt32)i; //OK u gets 1

Object o = i;
u = (UInt32)o; //throws System.InvalidCastException

I don't understand why. Is this a .Net bug?
Posted

It's because the cast operator can do two things, and you're confusing them here.

The first example is a converting cast; the value was an int, and you are casting it to a uint. This is defined to be a valid converting cast. If it were a user defined type, there would be an operator of the form
public static explicit operator uint(int value){ ... }

There are also implicit converting casts, for example
int i = 2;
double d = i;

Within the numeric types, all converting casts are (I think, anyway) valid; those which could possibly lose data or change its interpretation (narrowing and signed-unsigned conversions) are explicit, those which can't (widening) are implicit.


The second type of cast is a type reassignment. This only works if the thing you're trying to cast actually is of the type you're trying to cast it to (or has an explicit cast operator from that type). There is no explicit conversion cast defined from object to uint, and o is actually an int, not a uint, so the cast fails.

What you have to do in this situation is first get the int using a type reassignment cast (which will work because o actually is an int), and then use a converting cast on that:
uint u = (uint)(int)o;
 
Share this answer
 
Comments
BillWoodruff 21-Oct-11 6:28am    
+5 I learned something from this very articulate answer, thanks !
RaisKazi 21-Oct-11 6:35am    
Agree! my 5.
Use Convert.ToUInt32 Method.
http://msdn.microsoft.com/en-us/library/system.convert.touint32%28v=VS.100%29.aspx
C#
Int32 i = 1;
UInt32 u = (UInt32)i;

Object o = i;
u = Convert.ToUInt32(o);


One reason I see, it's does not supporting "u = (UInt32)o;" is - Data type UInt32 is not a CLS-compliant.
http://msdn.microsoft.com/en-us/library/system.uint32.aspx

Below links are also good to understand more on this.
http://msdn.microsoft.com/en-us/library/system.iconvertible.aspx
http://msdn.microsoft.com/en-us/library/12a7a7h3.aspx

Updated -
Reasons mentioned in Solution-1 and Solution-3 are equally correct, if you do Boxing as Object o = u; (UInt32 to object). And then do UnBoxing as u = Convert.ToUInt32(o); (object to UInt32 ) then it will work.
C#
Int32 i = 1;
UInt32 u = (UInt32)i;
Object o = u;
u = Convert.ToUInt32(o);

But if you are doing Boxing as Object o = i; (Int32 to object). And then do UnBoxing as u = Convert.ToUInt32(o); (object to UInt32 ) then it will throw an error, Because the Data type which you used while doing Boxing is not matching while doing Unboxing.
 
Share this answer
 
v5
Comments
BillWoodruff 21-Oct-11 6:27am    
Just figured out the same answer ! Good one +5
RaisKazi 21-Oct-11 6:31am    
Thank you Bill. :)
Shmuel Zang 21-Oct-11 8:34am    
It seems like the CLS-compliance issue isn't relevant for this question. But, 5 for the update.
RaisKazi 21-Oct-11 9:56am    
Yes Agree. :). Initially I thought it could be CLS issue, But yes it's purely Boxing-UnBoxing issue.

This exception is about Unboxing. You can perform Unboxing only to the type you have performed Boxing from.


The type of i is Int32 and the type you want to unbox to is UInt32.


You can change the last line of the example to:


C#
u = (UInt32)(Int32)o;

This line performs unboxing from a boxed Int32 to Int32 and, then performs casting from Int32 to UInt32.

 
Share this answer
 
v2
Comments
RaisKazi 21-Oct-11 6:49am    
My 5!
Shmuel Zang 21-Oct-11 8:19am    
Thanks.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900