zoukankan      html  css  js  c++  java
  • 装箱和拆箱的易错点整理总结

    .Net中装箱和拆箱操作,以及相关所做的事情大家应该是众所周知的事情,这里就截取书上的一些概念细节

     

     

     

     

     

     

     如果要在代码中显式的判断装箱后的引用类型的原始类型,可以 使用 is操作符判断  或者通过GetType()方法判断

    if(  o  is  Int32)  o.GetType()

    关注装箱和拆箱操作,关键的地方还是在性能问题上。正如上面解释的,装拆箱操作会涉及到给值类型堆空间分配,会涉及到复制值,还会有一些额外的无类型的变量,给GC带来一定的负担,所以我们应该避免装拆箱操作,特别的泛型是最常用的一种去减少装拆箱的方案。现在我们关注的是如果涉及到了的情况,一般我们可以写代码 让值类型变成引用类型,这种是显式的,还有一种是代码隐式的,  特别在一些调方法传参的时候做的一些隐式的类型转换,如果在一个循环下的话,性能问题就凸显出来了,比如最常见的 ArrayList(Array的一个复杂版本,支持动态添加,内部维护了一个Object的数组),和HashTable 。

    再一个典型例子:

     还有一种是枚举

    枚举可以被装箱成System.Object,System.ValueType.和System.Enum,以及System.Enum实现的三个接口类型System.Icomparable,System.IConvertible,System.Iformattable

    这是个例子: 

     

     再比如:

     GetType方法是由System.Object类型提供的,因此值类型调用的时候必须执行相应的装箱操作,而Object提供了几个虚方法,包括 ToString(),Equal(),GetHashCode(),Finalize(),这些有些值类型是进行重写了的,比如int32重写了ToString(),因此不会执行装箱操作

    这里你就会疑问,为什么 int和 enum 定义的枚举都是值类型,一个前者没有装箱,后者缺装箱了,这个我们可以从继承上挖一下

    其中int 对应的是Int32,是一个结构类型,他调的重写方法是int32下的方法

     而枚举类型 就不是了,他直接定义的是Enum下的,这里重写了ToString(), 可以看出Enum是个引用类型,所以装箱了,

     这里我们就引出了 enum 和Enum到底是不是一个东西,显然不是。

    enum是一个c#关键字,是c/c++/c#等c语系语言一种关键字.用于定义枚举类型.

    我们定义枚举类型的格式是 

    enum <enum_name> {enumeration list};

    枚举类型都是值类型,所有枚举类型都隐式地继承 System.Enum 类型,当然也同时继承了它的所有成员, System.Enum 类型是继承自 System.ValueType 类型唯一不为值类型的引用类型;System.Enum是一个抽象类(abstract class)

    所有的值类型都是System.ValueType的后代,枚举类型也不例外,枚举类型直接继承自System.Enum,而System.Enum却又直接继承自System.ValueType的,所以,枚举类型也是System.ValueType的后代。
    值类型都是System.ValueType的后代”,但System.ValueType的后代不全是值类型,System.Enum就是唯一的特例!

    在System.ValueType的所有后代中,除了System.Enum之外其它都是值类型.

    当然还有各种形形色色的装箱和拆箱例子,后期遇到新奇的,再一一收纳。其中看IL代码是最为直接的

  • 相关阅读:
    游千佛塔有感
    时刻坚持高标准:成大事者的十条“箴言”
    谁愿意嫁给我这样的人
    成功的秘诀之一,就是敢于提出大设想、大思考
    寒冬里的暖阳
    世界最伟大的管理原则
    把你藏在心里
    登天门有感
    办公室保持最佳状态的诀窍
    “领悟”的价值是什么?思维能力训练问答
  • 原文地址:https://www.cnblogs.com/wwkk/p/13443759.html
Copyright © 2011-2022 走看看