请先看下面一段代码:
int number;
object thing;
double bigNumber;number = 42;
thing = number;bigNumber = (double)thing;在运行时的时候会发生转型的错误(InvalidCastException异常)
thing是Object类型(引用类型),转换成double类型(值类型)
thing = number;这是一个box,装箱
为什么bigNumber = (double)thing拆箱的时候就会引发异常呢?
必须要bigNumber = (double)(int)thing;才可以。
假如number是double型  bigNumber = (double)thing;不会出错
我知道区别在哪,但是我想知道为什么,int转double不是隐式转换的么,为什么会出错呢?
难道我钻牛角了?

解决方案 »

  1.   

    因为装箱的对象类型为int,所以拆箱时只能拆箱成int,然后才能强制转换成double;拆箱时不存在隐式转换。其实所谓的隐式转换,就是编译器编译时自动替你完成了相关工作而已,而不是在运行时自动隐式转化,运行时实际还是相当于显示转化。拆箱是在运行时进行的,所以不存在隐式转化的能力
      

  2.   

    没钻牛角,只是你这句话的意思是想把用int装箱的对象拆箱为double,并不是拆箱为int后再转换
      

  3.   

    你的意思是强制转换和隐式转换是在编译器编译的时候就已经完成了?
    也就是说一个int型转double型的隐式转换在运行时的时候,实际是内存操作就是double型与double型之间的操作,没有int型转double型这操作,是因为这个操作在编译的时候就完成了是吗?
      

  4.   

    如果真是这样的话
    bigNumber = (double)thing;
    在运行时的时候这句话还真是少了一步隐式转换这一步,所以才出错的?
      

  5.   


    有道理!什么类型装箱,就只能拆箱成什么类型!
    这在NET很经常见到!
      

  6.   

    装进去什么就出来什么,装int想出来个double就出错
      

  7.   

    int转double是强制转换啊  怎么被LZ说成隐式了
      

  8.   


    这个兄弟说得就浅显易懂啦!装拆箱的时候会把默认的转换给屏“蔽掉”也就是int -> double 不会再执行
      

  9.   

    首先,需要说明一下何为装箱操作,以及在内存中是如何完成的?
    我们知道值类型是保存在栈上的,引用类型是保存在堆上的。那么装箱首先为值类型在托管堆上创建一个值类型的对象(该对象的内容将分配在托管堆上),在栈上将有一个引用指向这个刚刚创建的对象。
    例如:
    int i=1;
    object o = (object)i;
    i首先被分配在栈上,当执行第二句的时候会装箱,首先在托管堆上创建一个int类型的对象,然后将o指向这个int型的对象,此时int型对象的值是1,请注意其类型,此时这个类型是Int。其次,拆箱操作则将引用类型的“还原”到栈上,拆箱首先将引用对象转换成其对应的类型(这里是Int)。也就是此时你只能将这个引用型的对象拆箱到一个和Int兼容的数据类型上,如果你想将其拆箱到其他的数据类型时将会出现类型转换的异常。最后对于你的例子,你是将其装箱为一个Int类型,那么在拆箱的时候首先应该拆箱成一个Int类型,然后再将Int转换成一个double类型。
      

  10.   


     int number;
                object thing;
                double bigNumber;            number = 42;
                thing = number;            bigNumber = Convert.ToDouble( thing);
                textBox2.Text = bigNumber.ToString();
      

  11.   

    是隐式的啊
    int a;
    double b;
    b = a;//(int->double)隐式
    a = (int)double;//(double->int)强制
      

  12.   

    int不能隐性转换double   
    int   i=   2000;   
    object   o=   i;//对i进行装箱;o指向已装箱对象   
    double   nd=   (double)o;;  //先拆箱为正确的类型,然后在转型,这句会出错   
    因为当对一个对象执行拆箱操作时,转型的结果必须是原来未装箱时的类型int  
    这样就正确double   d=   (double)(int)o
      

  13.   

    int 难道不是隐式转换为double吗??  我不是很明白  我测试过就是隐式转换的阿
    2楼的说法倒是很有依据的   能再说明白点不??我知道装什么进去拆箱出来是什么  但是拆箱出来是int型  int转double不是隐式转换么  为什么还出错?
    除非是2楼的说法  拆箱的时候不支持隐式转换。
      

  14.   


    int tmp = 10;
    double b = tmp;
    int 是可以隐式转换的,但是在拆箱的过程中,原来的object类型只能转为int类型,而不能直接强制转换为double。也可以使用:double bigNumber= (int)thing;
      

  15.   

    第一句话我知道的  第二句原来的object类型只能转为int类型,而不能直接强制转换为double这一句是根据什么来判断的呢,我想知道的是理由。
    现在我能明白的是拆箱unbox之后,的确是int型,但是代码显示却要转型为double,也就是说在运行时拆箱之后是int型紧接着企图执行int到double的内存复制,但是这个企图是一个隐式的转换,但是在拆箱的时候并不支持隐式的,也就是说少了这一步(就是企图执行那一步),内存中int直接拷贝double是错误的,必须是显示转换后拷贝。
    晕了,说了这么多不知道大家明白我意思没
      

  16.   

    这个异常并不是拷贝引起的,.net创建新对象时会分配给实例一个类型标示,在没有重载的情况下做类型转换时会直接把2者的标示作比较,不是同一个类型则直接抛出异常,这些都是在编译时完成的,如果能全部放在运行时做这种转换就不必作2次转换了,不过执行效率会降低很多。
      

  17.   

    int number;
    object thing;
    double bigNumber;number = 42;
    thing = number;bigNumber = (double)thing;//此时thing是object类型,它封装的是int型,应该先把thing拆箱为int型
    因此,以下两种都是正确的:
    bigNumber = (double)(int)thing;
    bigNumber = (int)thing;
      

  18.   

    object是不能直接转换成double类型的,需要先进行一次int类型的转换,才能进行转换到double
      

  19.   

    bigNumber = (int)thing;
    是这样玩的吧,这才是你说的隐式转换啊
    你不能说 bigNumber = (double)thing; 
    这样做并不是隐式转换
      

  20.   

    17楼已经很好
    如果你想钻得彻底的话
    可以看《你必须知道的.NET》