【问题标题】:Why does (int)(object)10m throw "Specified cast is not valid" exception?为什么 (int)(object)10m 会抛出“Specified cast is not valid”异常?
【发布时间】: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;

【问题讨论】:

标签: c# casting


【解决方案1】:

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

您不想跳过多个强制转换,简单的值类型实现 IConvertible 接口。您使用 Convert 类调用它:

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

【讨论】:

    【解决方案2】:

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

    object o = d;
    

    如果不先拆箱,就不能直接转换装箱的值,这就是为什么直接转换为 int 会失败,如下所示:

    int x = (int)o;
    

    但是,通过这样做(中间先转换为小数):

    int x = (int)(decimal)o;
    

    您首先将 o 拆箱,这意味着您正在检索十进制值,然后将拆箱的十进制值转换为 int,这是因为 C# 支持将小数转换为 int。

    【讨论】:

      【解决方案3】:

      decimal 有一个 explicit cast operatorintobject 没有:

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

      【讨论】:

        【解决方案4】:

        这里你需要想到的是,装箱和拆箱并不完全是一种转换。您只需将对象类型“包装”在初始十进制类型周围。这就是为什么您需要先拆箱对象,然后才能将其转换为整数。

        【讨论】:

          猜你喜欢
          • 2012-09-15
          • 2023-02-15
          • 2022-09-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-06-05
          • 2020-05-26
          • 1970-01-01
          相关资源
          最近更新 更多