Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this cast from short to int fail?

We have some code that archives data from a Microsoft Access database into a MS SQL Server database. Assuming we have a data reader already populated from the Access table and we are adding a parameter to a SqlCommand in preparation for the insert, we have a typecast that is failing. Here is the code:

oSqlServerDbCmd_ForInsert.Parameters.AddWithValue("@Duration",
     (int) oReader["Duration"]);

The field from the oReader is actually an Access Integer, which is a short in C#. If we cast to a short here there is no problem. However, if we cast to an int the code throws an InvalidCastException. I may be misreading this from the MSDN documentation:

"There is a predefined implicit conversion from short to int, long, float, double, or decimal."

...but it sounds like this should work (my reasoning being, if an implicit conversion is defined why would an explicit typecast not work?). I realize the cast is not even necessary because AddWithValue accepts an object, so we have actually removed the cast from our code, but I would love to see an explanation as to why this cast was failing just in case we run into something like this in the future.

like image 524
A. Wilson Avatar asked Mar 16 '12 17:03

A. Wilson


2 Answers

What you have in your hands is an instance of unboxing. Specifically when unboxing, you can only unbox to the type of the value that was originally boxed; if that type is A and you are unboxing to B, it does not matter if an implicit conversion from A to B exists (the unboxing will still fail).

See Eric Lippert's classic blog post on the subject for an involved explanation.

like image 135
Jon Avatar answered Oct 15 '22 09:10

Jon


You have to cast to the very specific type since you are unboxing - the problem is that oReader["Duration"] returns an object instance:

short myShort = 42;
object o = myShort;
int myInt = (int)o; //fails

It will succeed if you cast back to short first, then to int:

(int) (short) oReader["Duration"]
like image 23
BrokenGlass Avatar answered Oct 15 '22 11:10

BrokenGlass