为什么从short到int的转换失败?

我们有一些代码将数据从Microsoft Access数据库归档到MS SQL Server数据库。 假设我们已经从Access表填充了数据读取器,并且我们正在为SqlCommand添加一个参数以准备插入,我们有一个失败的类型转换。 这是代码:

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

oReader中的字段实际上是一个Access Integer,它是C#的简称。 如果我们在这里投短,那就没问题。 但是,如果我们转换为int,则代码会抛出InvalidCastException。 我可能会误解MSDN文档 :

“存在从short到int,long,float,double或decimal的预定义隐式转换。”

…但听起来这应该有用(我的理由是,如果定义了隐式转换,为什么显式类型转换不起作用?)。 我意识到转换甚至不是必需的,因为AddWithValue接受了一个对象,所以我们实际上已经从我们的代码中移除了转换,但是我希望看到为什么这个转换失败的解释,以防万一我们遇到这样的事情未来。

你掌握的是拆箱的一个例子。 特别是在取消装箱时,您只能取消装箱最初装箱的值的类型; 如果该类型是A并且您要拆箱到B, 那么从A到B的隐式转换是否存在无关紧要 (拆箱仍然会失败)。

请参阅Eric Lippert关于该主题的经典博客文章 ,以获得相关解释。

因为你要拆箱,你必须转换为非常特定的类型 – 问题是oReader["Duration"]返回一个object实例:

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

如果先将其转换为short,然后转换为int,它将成功:

 (int) (short) oReader["Duration"]