【问题标题】:Why can't I cast boxed int to nullable decimal? [duplicate]为什么我不能将装箱的 int 转换为可为空的小数? [复制]
【发布时间】:2010-11-09 09:21:16
【问题描述】:

为什么会抛出 InvalidCastException?有人能描述一下我的这种行为吗?

object zero = 0;
decimal? dec = (decimal?)zero;

【问题讨论】:

  • @John Saunders:这是不合法的。

标签: c# .net


【解决方案1】:

装箱的int 只能拆箱为int。但是,这是合法的:

object zero = 0;
decimal? dec = (decimal?)(int)zero;

有关详细信息,请参阅 MSDN 或 ECMA 334 C# 规范。这里的关键是:

拆箱是从类型对象到值类型或从接口类型到实现接口的值类型的显式转换。拆箱操作包括:

  1. 检查对象实例以确保它是给定值类型的装箱值。
  2. 将值从实例复制到值类型变量中。

编辑:这个链接的article 值得退出 cmets。谢谢罗布·肯尼迪!

【讨论】:

  • 好的,但是为什么需要这种临时转换?
  • 第一次强制转换 (int) 将装箱的 int 拆箱为 int 类型的值类型(这是合法操作)。第二个转换(十进制?)将结果 int 转换为十进制?。
  • 微软(有充分的理由)从来没有为对象写一个隐式强制转换重载到十进制。
  • @Michael Meadows:这是合法的:对象零 = 0m;十进制? dec =(十进制)零;注意'm'明确告诉编译器文字“0”将被解释为十进制。
  • Eric Lippert 详细介绍了为什么它会这样工作。总结:对除原始类型以外的任何内容进行拆箱将涉及很多针对所有不同可能性的生成代码,因为编译器不知道原始装箱类型是什么。 blogs.msdn.com/ericlippert/archive/2009/03/19/…
【解决方案2】:

看这篇文章 http://msdn.microsoft.com/en-us/magazine/cc301569.aspx

具体来说 “公共语言运行时首先确保引用类型变量不为空,并且它引用的对象是所需值类型的装箱值。如果任一测试失败,则会生成 InvalidCastException 异常。”

我认为您在该值的对象上失败了。我认为对 int 的覆盖是有效的,因为 0 文字将转换为 int,然后将 int 转换为十进制。

如果你这样做,它会起作用

    decimal? test=0;
    object zero = test;
    decimal? dec = (decimal?)zero;

但我认为您的 sn-p 中的“0”不是“十进制”类型。

我仍然不肯定,因为这得到了同样的异常。

        int test=0;
        object zero = test;
        decimal? dec = (decimal?)zero;

【讨论】:

  • 我的问题最初来自以下方法: public TResult Convert(object value) { try { return (TResult)value; } 捕捉 (InvalidCastException) { 返回默认值(TResult);此方法在调用时返回 null:Convert(0);我不能对 TResult 做出任何假设,也不知道究竟是什么作为论据。这就是为什么我不能使用 Convert.To...() 好东西。
猜你喜欢
  • 2010-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-12
  • 2012-07-18
  • 2013-09-22
  • 2016-06-12
相关资源
最近更新 更多