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

Hom*_*mam 39 c# casting

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

decimal d = 10m;
object o = d;
int x = (int)o;
Run Code Online (Sandbox Code Playgroud)

但这有效:

int x = (int)(decimal)o;
Run Code Online (Sandbox Code Playgroud)

Han*_*ant 73

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

您不希望跳过多个演员箍,简单的值类型实现IConvertible接口.您使用Convert类调用的:

        object o = 12m;
        int ix = Convert.ToInt32(o);
Run Code Online (Sandbox Code Playgroud)


Bol*_*ock 21

当你这样做时,你隐含地将小数装箱d到基本对象:

object o = d;
Run Code Online (Sandbox Code Playgroud)

如果没有先将其取消装箱,则无法直接转换盒装值,这就是为什么直接转换为int,如下所示,会失败:

int x = (int)o;
Run Code Online (Sandbox Code Playgroud)

但是,通过执行此操作(首先中间转换为小数):

int x = (int)(decimal)o;
Run Code Online (Sandbox Code Playgroud)

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


Fré*_*idi 9

decimal有一个显式类型转换操作符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.
Run Code Online (Sandbox Code Playgroud)