我们有一些代码可以将数据从Microsoft Access数据库存档到MS SQL Server数据库中。假设我们已经从Access表填充了数据读取器,并且我们正在为SqlCommand添加一个参数以准备插入,我们有一个失败的类型转换。这是代码:
oSqlServerDbCmd_ForInsert.Parameters.AddWithValue("@Duration",
(int) oReader["Duration"]);
oReader中的字段实际上是一个Access Integer,它是C#的简称。如果我们在这里投短,那就没问题了。但是,如果我们转换为int,则代码会抛出InvalidCastException。我可能会误解MSDN documentation:
“存在从short到int,long,float,double或decimal的预定义隐式转换。”
...但听起来这应该有效(我的理由是,如果定义了隐式转换,为什么显式类型转换不起作用?)。我意识到转换甚至不是必需的,因为AddWithValue接受了一个对象,所以我们实际上已经从我们的代码中移除了转换,但我希望看到一个解释为什么这个转换失败,以防万一我们遇到这样的事情未来。
答案 0 :(得分:18)
您手中的内容是 unboxing 的一个实例。特别是在取消装箱时,您只能取消装箱最初装箱的值的类型;如果该类型是A并且你要拆箱到B,那么是否存在从A到B的隐式转换(拆箱仍然会失败)。
请参阅Eric Lippert关于该主题的classic blog post以获得相关解释。
答案 1 :(得分:5)
您必须转换为特定类型,因为您要拆箱 - 问题是oReader["Duration"]
会返回object
个实例:
short myShort = 42;
object o = myShort;
int myInt = (int)o; //fails
如果先退回到短路,然后转到int:
,它会成功(int) (short) oReader["Duration"]