【发布时间】:2011-04-26 14:05:02
【问题描述】:
为什么这个显式转换会抛出 Specified cast is not valid. 异常?
decimal d = 10m;
object o = d;
int x = (int)o;
但这有效:
int x = (int)(decimal)o;
【问题讨论】:
为什么这个显式转换会抛出 Specified cast is not valid. 异常?
decimal d = 10m;
object o = d;
int x = (int)o;
但这有效:
int x = (int)(decimal)o;
【问题讨论】:
装箱的值只能拆箱为完全相同类型的变量。这个看似奇怪的限制是一个非常重要的速度优化,它使 .NET 1.x 在泛型可用之前变得可行。您可以在this answer 阅读更多相关信息。
您不想跳过多个强制转换,简单的值类型实现 IConvertible 接口。您使用 Convert 类调用它:
object o = 12m;
int ix = Convert.ToInt32(o);
【讨论】:
当你这样做时,你隐含地将十进制 d 装箱到一个基本对象:
object o = d;
如果不先拆箱,就不能直接转换装箱的值,这就是为什么直接转换为 int 会失败,如下所示:
int x = (int)o;
但是,通过这样做(中间先转换为小数):
int x = (int)(decimal)o;
您首先将 o 拆箱,这意味着您正在检索十进制值,然后将拆箱的十进制值转换为 int,这是因为 C# 支持将小数转换为 int。
【讨论】:
decimal 有一个 explicit cast operator 到 int。 object 没有:
decimal d = 10m;
object o = d;
int x = (int)d; // OK, calls decimal.explicit operator int(d).
int y = (int)o; // Invalid cast.
【讨论】:
这里你需要想到的是,装箱和拆箱并不完全是一种转换。您只需将对象类型“包装”在初始十进制类型周围。这就是为什么您需要先拆箱对象,然后才能将其转换为整数。
【讨论】: