Why can't I unbox an int as a decimal?
我有一个
1 | decimal d = (decimal)reader[0]; |
出于某种原因,这会引发一个无效的强制转换异常,表示"指定的强制转换无效"。
当我这样做时,它告诉我它是一个整数。据我所知,这不应该是个问题……
我用这段代码测试了这一点,效果很好。
1 2 | int i = 3750; decimal d = (decimal)i; |
这让我抓耳挠腮,想知道为什么它不能将读卡器中包含的int作为一个十进制值拆封。
有人知道为什么会发生这种情况吗?有什么我不知道的吗?
只能将值类型取消绑定到其原始类型(以及该类型的可空版本)。
顺便说一下,这是有效的(只是两行版本的简写):
1 2 | object i = 4; decimal d = (decimal)(int)i; // works even w/o decimal as it's a widening conversion |
出于这个原因,阅读这篇埃里克·利珀特的博客文章:代表性和身份
就我个人而言,我将通过强制转换语法完成的操作分为四种不同的操作类型(它们都有不同的IL指令):
这是一个简单的解决方案。它负责拆箱,然后转换为小数。对我来说工作很好。
1 | decimal d = Convert.ToDecimal(reader[0]); // reader[0] is int |
将
要将
1 | decimal d = (decimal)(int)reader[0]; |
IDataRecord接口还具有取消绑定值的方法:
1 | decimal d = (decimal)reader.GetInt32(0); |
阿夫沙里说:
You can only unbox a value type to its original type (and the nullable
version of that type).
要认识到的是,铸造和拆箱之间有区别。杰里耶瓦尔说得很好
In a sense it's a shame that unboxing and casting syntactically look
identical, since they are very different operations.
铸造:
1 2 | int i = 3750; // Declares a normal int decimal d = (decimal)i; // Casts an int into a decimal > OK |
装箱/拆箱:
1 2 | object i = 3750; // Boxes an int ("3750" is similar to"(int)3750") decimal d = (decimal)i; // Unboxes the boxed int into a decimal > KO, can only unbox it into a int or int? |