Day17

今天做了一天的车,没能看电脑上的教材,不过在kindle上看了另外一本书,前面几章的内容恰好也是基础,就当是巩固了前几天复习的内容,比如unity中各回调函数的执行顺序,协程,值和引用。其中恰巧还看到了比较详细的装箱和拆箱的解释,之前看到这两个概念并不是很理解,今天看完简直茅塞顿开,也算是不错的收获。

装箱
书中是以将一组Vector3数据放到ArrayList中为例子讲解的,Vector3类型本身是值类型,当程序执行ArrayList.Add的时候,因为Add方法的参数是一个Object类型,也就是Add方法的参数是引用类型的变量,所以为了使代码能够正常运行,Vector3值类型的实例在这里必须转换成真正在托管堆上分配的对象,且必须获得对该对象的引用,所以装箱过程为:
1. 在托管堆中分配内存,这个内存空间包括值类型各个字段所需的内存,以及托管堆所有对象都有的两个额外成员——类型对象指针和同步索引块的内存。
2. 将值类型的字段复制到新分配的对内存中。
3. 返回对象地址,即对象的引用。值类型就成了引用类型。

所以托管堆中的对象的值只是原始值的一个副本,即改变原始值是不会改变箱内的值的。装箱后的Vector3的对象会一直存在于托管堆中,直至被垃圾回收。

拆箱
在获取ArrayList中的元素时就执行了拆箱操作。即,获取已经装箱的Vector3对象中,也就是ArrayList中各个字段的地址的过程即为拆箱。
所以拆箱的代价要比装箱小。
但是在拆箱后,还需要有一步复制的过程,即,将ArrayList中各个字段的值从托管堆上复制到线程栈的新的值类型Vector3的实例v中。
拆箱+复制 = 获取ArrayList中的某项的值。

所以装箱、拆箱和复制这整个过程会对程序的速度和内存空间产生不利的影响,甚至可能会由于频繁地操作托管堆而增加GC的次数,因此装箱、拆箱和复试的操作越少越好。所以在日常开发过程中,ArrayList不常用,List< T >更常用。

其实List< T >内部也是用ArrayList实现的,但是List< T >确保了类型安全,取消了装箱和拆箱的操作,以及由于引入泛型而无需运行时进行类型检查,融合了Array可以快速访问的优点以及ArrayList长度可以灵活变化的有点。

C#中的链表是LinkedList< T >,以前一直以为是List< T >,真是蠢死。。。
C#中与链表配套的是链表的结点类LinkedListNode< T >。
MSDN中链表类的说明

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值