简体   繁体   English

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

[英]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. 我们有一些代码将数据从Microsoft Access数据库存档到MS SQL Server数据库中。 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. 假设我们已经从Access表填充了数据读取器,并且我们正在为SqlCommand添加一个参数以准备插入,我们有一个失败的类型转换。 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#. oReader中的字段实际上是一个Access Integer,它是C#的简称。 If we cast to a short here there is no problem. 如果我们在这里投短,那就没问题了。 However, if we cast to an int the code throws an InvalidCastException. 但是,如果我们转换为int,则代码会抛出InvalidCastException。 I may be misreading this from the MSDN documentation : 我可能会误解MSDN文档

"There is a predefined implicit conversion from short to int, long, float, double, or decimal." “有一个预定义的从short到int,long,float,double或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. 我意识到转换甚至不是必需的,因为AddWithValue接受了一个对象,所以我们实际上已经从我们的代码中移除了转换,但我希望看到一个解释为什么这个转换失败,以防万一我们遇到这样的事情未来。

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). 如果该类型是A并且您要拆箱到B, 那么从A到B的隐式转换是否存在无关紧要 (拆箱仍然会失败)。

See Eric Lippert's classic blog post on the subject for an involved explanation. 请参阅Eric Lippert关于该主题的经典博客文章 ,以获得相关解释。

You have to cast to the very specific type since you are unboxing - the problem is that oReader["Duration"] returns an object instance: 因为你要拆箱,你必须转换为非常特定的类型 - 问题是oReader["Duration"]返回一个object实例:

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

It will succeed if you cast back to short first, then to int: 如果你先回到short,然后再转到int,它会成功:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM