footleg

导航

关于.NET中的值类型和引用类型



        .NET中的值类型和引用类型,这是一个最基础的问题,我也一直以为自己是知道的,所以也没有深究。直到前几天得到达人指点,才陡然明白,原来自己一直到不知道值类型和引用类型的本质。
        目前市面上可见的大部分教授C#的书籍都会首先讲解数据类型,而且往往都会告诉大家:值类型是存在堆栈里面的,引用类型是存在堆里面的。
        达人告诉我,这个必须要从.NET的一个执行机制来看。.NET的程序首先被编译为IL程序,然后再托管执行。这个时候给值类型和引用类型的内存分配是不一样的。值类型直接从堆栈里面取值就可以了,引用类型必须要先从堆栈里面取出它的地址,再根据这个地址到堆里面找到对应的值。
        这就引出了一个问题,int是典型的值类型,class是典型的引用类型,如果我在一个class里面,有诸如int i=0;的语句,那么变量i究竟是存在堆里面还是堆栈里面?
        这个问题可以这样来解释,因为class是引用类型,所以一开始的时候i肯定是存在堆里面的,但是,当执行的时候,IL会把i取到堆栈里面。
        说到引用类型和值类型,就不得不提到Boxing和Unboxing,基本上进行.NET编程的同学们都知道Boxing是把值类型装箱成引用类型,Unboxing是把引用类型拆箱成值类型,但是为什么一定只能拆箱回原有的数据类型呢?
        这个问题,又绕回来了,还是内存分配的问题。装箱是把值类型从堆栈里面取出来,包装一下,作为引用类型存到堆里面去,装箱是把这个包装过的引用类型,从堆里面拿出来,去掉那些包装,把它放回到堆栈里面去。既然这样,中间肯定存在一个内存分配的问题,所以,必须要是原来的类型,否则内存分配不就乱了么?这也能够解释,为什么在我们编程的时候被要求尽量少装箱拆箱,因为这样装来拆去真的是耗时耗力,影响效率。

posted on 2006-10-25 16:27  迷途  阅读(202)  评论(0编辑  收藏  举报