我有一个 IDataRecord 阅读器
,我正在从中检索小数,如下所示:
decimal d = (decimal)reader[0];
出于某种原因,这会抛出一个无效的强制转换异常,指出“指定的强制转换无效。”
当我执行 reader[0].GetType()
时,它告诉我它是一个 Int32。据我所知,这应该不是问题....
我已经通过这个运行良好的代码片段对此进行了测试。
int i = 3750;
decimal d = (decimal)i;
这让我摸不着头脑,想知道为什么它无法将读取器中包含的 int 拆箱为十进制数。
有谁知道为什么会发生这种情况?有什么我遗漏的微妙之处吗?
最佳答案
您只能将值类型拆箱为其原始类型(以及该类型的可空版本)。
顺便说一下,这是有效的(只是两行版本的简写):
object i = 4;
decimal d = (decimal)(int)i; // works even w/o decimal as it's a widening conversion
关于这背后的原因,请阅读 Eric Lippert's blog entry: Representation and Identity
就我个人而言,我将通过 cast 语法完成的事情分为四种不同类型的操作(它们都有不同的 IL 指令):
- 装箱(
box
IL 指令)和拆箱(unbox
IL 指令) - 通过继承层次进行转换(如C++中的
dynamic_cast<Type>
,使用castclass
IL指令来验证) - 原始类型之间的转换(如 C++ 中的
static_cast<Type>
,有大量 IL 指令用于原始类型之间的不同类型转换) - 调用用户定义的转换运算符(在 IL 级别,它们只是对适当
op_XXX
方法的方法调用)。
关于c# - 为什么我不能将 int 拆箱为小数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1085097/