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

49

为什么这个显式转换会抛出“指定的转换无效”异常?

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

但是这个可以工作:

int x = (int)(decimal)o;

4个回答

91

一个装箱的值只能解箱到完全同样类型的变量中。这个看似奇怪的限制是 .NET 1.x 在泛型还未出现时非常重要的速度优化。你可以在这个答案中阅读更多相关信息。

如果不想跳过多次强制转换,简单值类型实现了 IConvertible 接口。你可以使用 Convert 类来调用该接口:

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

23

当你这样做时,你隐式地将十进制数 d 装箱为一个基本对象:

object o = d;

若要进行强制类型转换,你需要先将装箱后的值拆箱,这也是为什么直接将其强制转换为int会失败的原因:

int x = (int)o;

然而,通过这样做(首先中间转换为十进制):

int x = (int)(decimal)o;

您首先解包o,这意味着您正在检索十进制值,然后将未打包的十进制值转换为int,这是有效的,因为C#支持将十进制转换为int。


10

decimal有一个显式转换运算符intobject没有:

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

3

这里需要注意的是,装箱和拆箱并不完全是一种转换。你只是把对象类型“围绕”初始的十进制类型“包裹”。这就是为什么在将其转换为整数之前,您需要先进行拆箱。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接