为什么(int)(对象)10m抛出“指定的强制转换无效”异常?

时间:2010-10-17 13:30:23

标签: c# casting

为什么这个显式转换会抛出Specified cast is not valid.异常?

decimal d = 10m;
object o = d;
int x = (int)o;

但这有效:

int x = (int)(decimal)o;

4 个答案:

答案 0 :(得分:71)

盒装值只能拆分为完全相同类型的变量。这个看似奇怪的限制是一个非常重要的速度优化,使得.NET 1.x在泛型可用之前可行。您可以在this answer中了解有关它的更多信息。

您不想跳过多重演员箍,简单的值类型实现IConvertible接口。您使用Convert类调用它:

        object o = 12m;
        int ix = Convert.ToInt32(o);

答案 1 :(得分:19)

执行此操作时,您隐式将小数d装入基本对象:

object o = d;

如果没有首先取消装箱,就不能直接转换盒装值,这就是为什么直接转换为int,如下所示,会失败:

int x = (int)o;

然而,通过这样做(先中间转换为小数):

int x = (int)(decimal)o;

您首先取消装箱o,这意味着您正在检索小数值,然后将未装箱的十进制值转换为int,这是有效的,因为C#支持将小数点转换为整数

答案 2 :(得分:9)

decimal有一个explicit cast operatorintobject没有:

decimal d = 10m;
object o = d;
int x = (int)d;  // OK, calls decimal.explicit operator int(d).
int y = (int)o;  // Invalid cast.

答案 3 :(得分:3)

你需要考虑的是装箱和拆箱并不是一种转换。您只需将对象类型“包裹”在初始十进制类型“周围”。这就是为什么在能够将对象转换为整数之前需要首先取消对象的原因。