Implicit and explicit numeric casts are usually pretty straightforward:
- int i = 5;
- float f = i; // Implicit cast from Int32 to Single
- Byte b = (Byte) i; // Explicit cast from Int32 to Byte
- Object i = 5;
- float l = (float) i; // System.InvalidCastException: Specified cast is not valid.
- ArrayList a = new ArrayList();
- int b;
- for (int i = 0; i < 10; i++) {
- b = 10;
- a.Add(b);
- }
- float f = (float) a[0]; // System.InvalidCastException: Specified cast is not valid.
Why is a cast from int to float ok, but a cast from int ArrayList[i] to float not ok?
Type Casting vs Numeric Casting
Our InvalidCastException is not coming from our Explicit Cast from int to float. Our exception is coming from our Unboxing an int to float.
A key difference between Value Types and Reference Types is where they get allocated. Value Types are allocated in the current Thread Stack. Reference Types are allocated in the Managed Heap (think garbage collection).

Boxing is the act of casting a Value Type to a Reference Type.

We are Boxing when we do things like:
- Assign value types to reference type fields.
- Add value types to a collection reference type.
- Pass a value type as a parameter to a method that takes a reference type.
Unboxing is the act of casting a Reference Type to a Value Type.


We are Unboxing when we do things like:
- Extract a value type from a reference type.
- Extract a value type from a collection of value types.
- Pass a boxed value type to a method that takes a value type.
Unboxing’s Constraints
During Unboxing, two constraints get checked by the CLR:
- If the variable containing the reference to the boxed value type instance is null, a NullReferenceException is thrown.
- If the reference doesn’t refer to an object that is a boxed instance of the desired value type, an InvalidCastException is thrown.

- Object i = 5; // Boxing int 5 into reference type Object
- float l = (float)i; // Trying to unbox int b to float
- ArrayList a = new ArrayList();
- int b;
- for (int i = 0; i < 10; i++)
- {
- b = 10;
- a.Add(b); // Boxing int b into reference type ArrayList
- }
- float f = (float) a[0]; // Trying to unbox int b to float
So now that we understand the problem, what’s the solution?
System.Convert Namespace
If you look at the .NET Reference Source for System.Int32, you’ll notice that it implements IConvertible.
- public struct Int32 :
- IComparable,
- IFormattable,
- IConvertible,
- IComparable<Int32>,
- IEquatable<Int32>
Here’s the definition of System.Convert.ToSingle from the .NET Reference Source:
- /// <internalonly/>
- float IConvertible.ToSingle(IFormatProvider provider)
- {
- return Convert.ToSingle(m_value);
- }
- Our corrected examples:
- Object o = 5;
- float f = Convert.ToSingle(o);
- ArrayList a = new ArrayList();
- int b;
- for (int i = 0; i < 10; i++)
- {
- b = 10;
- a.Add(b);
- }
- Convert.ToSingle(a[0]);
Summary
We ran into a runtime exception when trying to do an explicit numeric cast that is usually successful.
The real cause of the issue is the way that we were casting from a Value Type to a Reference Type and then back to a Value Type. This is called Boxing and Unboxing. One of the rules of Unboxing is that we can only Unbox into the same Value Type we started with. Otherwise, we throw an InvalidCastException at runtime.
Our solution is to take advantage of the System.Convert static class. It provides us with a .ToXXX method that can be called for Value Types that implement IConvertible.
Hope this finds its way to you if/when you run into this problem, or it helps you stay aware of what the CLR is doing behind the scenes. As always, feel free to leave a comment below.

Nick ChamberlainPosted Jan 7, 2016, 8:08 AM
Thanks for your kind words everyone! I have a lot more content just like this on my blog @ http://buildplease.com. Please be sure to check it out and sign up for my newsletter!
Muhammad Aqib ShehzadPosted Jan 5, 2016, 7:40 AM
Good Share
Raja TPosted Jan 3, 2016, 11:52 PM
Nice, Thanks for sharing
Manas MohapatraPosted Jan 3, 2016, 11:27 AM
Informative one..
Sridhar SharmaPosted Jan 3, 2016, 11:00 AM
Nice Share :)
Humayun Kabir MamunPosted Jan 3, 2016, 12:14 AM
Nice...
Santhakumar MunuswamyPosted Jan 2, 2016, 10:16 PM
Thanks for nice share
Pankaj Kumar ChoudharyPosted Jan 2, 2016, 8:34 PM
Nice Explain Thanks to share............