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

Why does (int)(object)10m throw “Specified cast is not valid” exception?

为什么这个显式强制转换会引发Specified cast is not valid.异常?

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

但这是可行的:

1
int x = (int)(decimal)o;


装箱值只能与完全相同类型的变量解除装箱。这个看似奇怪的限制是一个非常重要的速度优化,使得.NET 1.x在泛型可用之前是可行的。你可以在这个答案中了解更多。

您不希望跳过多个强制转换环,简单的值类型实现IConvertible接口。通过使用convert类调用:

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


执行此操作时,您将隐式地将十进制d装箱到基本对象:

1
object o = d;

如果不首先取消装箱,则无法直接强制转换装箱值,这就是为什么直接强制转换为int失败的原因,如下所示:

1
int x = (int)o;

但是,通过这样做(中间先转换为十进制):

1
int x = (int)(decimal)o;

首先取消绑定o,这意味着要检索十进制值,然后将未绑定的十进制值强制转换为int,因为c支持将小数强制转换为int。


decimalint有一个显式的强制转换运算符。object不:

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

你需要考虑的是,拳击和拆箱并不是一种转换。只需将对象类型"环绕"在初始的十进制类型上。这就是为什么在将对象转换为整数之前,需要先取消对象的装箱。