将double转换为十进制时,为什么会出现InvalidCastException

我正在尝试调试获取InvalidCastException的应用程序。 失败的路线是

decimal d = (decimal)row[denominator]; 

在调试器中检查这个(见下面的截图),row [denominator]包含一个值为8.0的double,据我所知。 很可能没有任何问题将其转换为小数?

(’row’类型来自3. party库 ,它再次来自MySQL的数据。当针对较旧的MySQL服务器进行测试时会出现问题,该服务器显然会在MySQL 5.1上将某些聚合返回为double vs decimal – 同样的查询,完全相同数据库中的数据副本)

Visual Studio截图http://img18.imageshack.us/img18/3897/invaldicast.png

有关如何进一步调查此问题的任何帮助?

Eric Lippert已经在博客中深入探讨了这一点。 我一致认为它不直观,但他解释得很好: 代表和身份

你需要将它转换为双倍,因为row[denominator]是一个双重盒子作为对象,即

 decimal d = (decimal)((double)row[denominator]); 

我试试

 decimal d = Convert.ToDecimal(row[denominator]); 

要么

 decimal d = 0; if (!decimal.TryParse(row[denominator], out d)) //do something 

您可以使用:

 double d1 = (double)row[denominator]; decimal d = (decimal) d1; 

或者,当然,缩短到:

 decimal d = (decimal) (double)(row[denominator]); 

因为涉及拆箱步骤,所以需要2个步骤。

建议:尝试使用Convert.ToDecimal()而不是直接转换。

首先尝试将其转换为doublerow[denominator]被加框,因此直接转换为decimal将不起作用。

从错误消息和描述来看,我假设row [denominator]是一个盒装双,因此类型为object。 取消装箱只能对正确的底层数据类型进行,因为运行时现在不在哪里找到实际的转换操作符从double到decimal(在你的情况下,它试图找到一个将对象转换为十进制的运算符,但那个是一个拆箱操作符和底层类型不是十进制的。所以正确的方法应该是先转换为double然后再转换为十进制:

 decimal d = (decimal)(double)row[denominator]; 

做就是了

 decimal d = Convert.ToDecimal(row[denominator]); 

这样,您不必担心所有的铸造问题。