zoukankan      html  css  js  c++  java
  • 关于.NET中的值类型和引用类型



            .NET中的值类型和引用类型,这是一个最基础的问题,我也一直以为自己是知道的,所以也没有深究。直到前几天得到达人指点,才陡然明白,原来自己一直到不知道值类型和引用类型的本质。
            目前市面上可见的大部分教授C#的书籍都会首先讲解数据类型,而且往往都会告诉大家:值类型是存在堆栈里面的,引用类型是存在堆里面的。
            达人告诉我,这个必须要从.NET的一个执行机制来看。.NET的程序首先被编译为IL程序,然后再托管执行。这个时候给值类型和引用类型的内存分配是不一样的。值类型直接从堆栈里面取值就可以了,引用类型必须要先从堆栈里面取出它的地址,再根据这个地址到堆里面找到对应的值。
            这就引出了一个问题,int是典型的值类型,class是典型的引用类型,如果我在一个class里面,有诸如int i=0;的语句,那么变量i究竟是存在堆里面还是堆栈里面?
            这个问题可以这样来解释,因为class是引用类型,所以一开始的时候i肯定是存在堆里面的,但是,当执行的时候,IL会把i取到堆栈里面。
            说到引用类型和值类型,就不得不提到Boxing和Unboxing,基本上进行.NET编程的同学们都知道Boxing是把值类型装箱成引用类型,Unboxing是把引用类型拆箱成值类型,但是为什么一定只能拆箱回原有的数据类型呢?
            这个问题,又绕回来了,还是内存分配的问题。装箱是把值类型从堆栈里面取出来,包装一下,作为引用类型存到堆里面去,装箱是把这个包装过的引用类型,从堆里面拿出来,去掉那些包装,把它放回到堆栈里面去。既然这样,中间肯定存在一个内存分配的问题,所以,必须要是原来的类型,否则内存分配不就乱了么?这也能够解释,为什么在我们编程的时候被要求尽量少装箱拆箱,因为这样装来拆去真的是耗时耗力,影响效率。
  • 相关阅读:
    对宏的另外一些认识 及 assert.h的实现细节
    不要想太多
    线段树
    SQL基础 利用SELECT检索数据
    hidden表单值无法重置的缺陷
    oracle 数据库登陆
    基于ejb3,对JDBC进行封装,让使用JDBC时能像hibernate使用annotation注解一样简便,而且更加轻巧
    GoJS的一些使用技巧
    GoJS的学习使用
    灵活使用trim方法
  • 原文地址:https://www.cnblogs.com/footleg/p/539683.html
Copyright © 2011-2022 走看看