为什么我不能取消一个int作为小数?
我有一个IDataRecord reader ,我正在检索一个小数,如下所示: 
 decimal d = (decimal)reader[0]; 
由于某种原因,这会抛出一个无效的转换exception,说“指定的转换无效”。
 当我做reader[0].GetType()它告诉我,它是一个Int32。 据我所知,这不应该是一个问题…. 
我已经testing了这个片段,这工作得很好。
 int i = 3750; decimal d = (decimal)i; 
这让我挠脑袋,想知道为什么它不能将读取器中包含的int作为十进制数来打开。
有谁知道为什么这可能会发生? 我错过了些微妙的东西吗?
您只能将值types取消为原始types(以及该types的可为空的版本)。
顺便说一句,这是有效的(只是你的两行版本的简写):
 object i = 4; decimal d = (decimal)(int)i; // works even w/o decimal as it's a widening conversion 
为此,请阅读Eric Lippert的博客文章:表示和身份
就我个人而言,我将通过强制语法完成的事情分为四种不同types的操作(它们都有不同的IL指令):
-  拳击( boxIL指令)和拆箱(unboxIL指令)
-  通过inhertiance层次结构(如C ++中的dynamic_cast<Type>,使用castclassIL指令进行validation)
-  在原始types之间进行转换(如C ++中的static_cast<Type>,对于原始types之间的不同types的转换,有很多IL指令)
-  调用用户定义的转换运算符(在IL级别,他们只是方法调用适当的op_XXX方法)。
 将int为decimal是没有问题的,但是当你拆箱的时候,你必须使用对象所包含的确切types。 
 要将int值解包为一个decimal值,您首先将其解包为一个int,然后将其转换为十进制: 
 decimal d = (decimal)(int)reader[0]; 
IDataRecord接口也有拆箱的方法:
 decimal d = (decimal)reader.GetInt32(0); 
这是一个简单的解决scheme。 它需要照顾拆箱,然后铸造到十进制。 为我工作得很好。
 decimal d = Convert.ToDecimal(reader[0]); // reader[0] is int 
Mehrdad Afshari说:
您只能将值types取消为原始types(以及该types的可为空的版本)。
要实现的事情是铸造和拆箱是有区别的 。 杰里耶夫有一个很好的评论
从某种意义上说,拆箱和铸造在句法上看起来是完全相同的,因为它们是非常不同的操作。
铸件:
 int i = 3750; // Declares a normal int decimal d = (decimal)i; // Casts an int into a decimal > OK 
拳击/拆箱:
 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?