Why does (int)(object)10m throw “Specified cast is not valid” exception?
为什么这个显式强制转换会引发
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); |
执行此操作时,您将隐式地将十进制
1 | object o = d; |
如果不首先取消装箱,则无法直接强制转换装箱值,这就是为什么直接强制转换为int失败的原因,如下所示:
1 | int x = (int)o; |
但是,通过这样做(中间先转换为十进制):
1 | int x = (int)(decimal)o; |
首先取消绑定
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. |
你需要考虑的是,拳击和拆箱并不是一种转换。只需将对象类型"环绕"在初始的十进制类型上。这就是为什么在将对象转换为整数之前,需要先取消对象的装箱。