• CLR via #C读书笔记三:基元类型、引用类型和值类型


    1、一些开发人员说应用程序在32位操作系统上运行,int代表32位整数;在64位操作系统上运行,int代表64位整数。这个说法是完全错误的。C#的int始终映射到System.Int32,所以不管在什么操作系统上运行,代表的都是32位整数。

    2、checked、unchecked来检查、不检查表达式是否产生溢出;C#默认关闭溢出检查;

    UInt32 invalid=unchecked((UInt32)(-1));

    -----------------------------------------------------------

    Byte b=100;

    b=checked((Byte)(b+200));//抛出OverflowException异常

    3、System.Decimal是非常特殊的类型,CLR不将他视为基元类型;没有相应的IL指令来处理Decimal值,所以checked和unchecked操作符、语句以及编译器开关都失去了作用;

    4、引用类型总是从托管堆分配,C#的new操作符返回对象内在地址——即指向对象数据的内存地址;

    5、所有值类型都称为结构或枚举,所有结构都是抽象类型System.ValueType的直接派生类;System.ValueType本身又直接从System.Object派生;所有枚举都从System.Enum抽象类型派生,System.Enum从System.ValueType派生;

    6、值类型转换成引用类型要使用装箱机制;反向转换,就是拆箱。但是拆箱,就是获取堆中各字段的地址,并不包含复制数值过程,但是往往紧接着会发生一次字段复制。

      装箱机制

      1.在托管堆中分配内存。分配的内存量是值类型各字段所需的内存量,还要加上托管堆所有对象都有的两个额外成员(类型对象指针和同步块索引)所需的内存量。

      2.值类型的字段复制到新分配的堆内存。

      3.返回对象地址。现在该地址是对象引用;值类型成了引用类型。

    7、泛型集合在操作值类型的集合时不需要对集合中的项进行装箱/拆箱(因为一般的数组、非泛型集合如ArrayList类,是引用类型,增加值类型元素时要装箱)。单这一项改进,就使用性能提升了不少。这是因为托管堆中需要创建的对象减少了,进而减少了应用程序需要执行的垃圾回收的次数。

    8、如果值类型要调用基类的方法(如非虚的、继承的方法),必须装箱,以便能够通过this指针将一个堆对象的引用传给基类;

    9、拆箱后如果复制数据到线程栈中,并且修改栈的数据,原堆中的数据不受影响;

  • 相关阅读:
    寒假作业4
    UVA5870 乱搞 Smooth Visualization
    UVA5874 Social Holidaying 二分匹配
    UVA5876 Writings on the Wall 扩展KMP
    hdu1231 最大连续子序列
    hdu3535 混合背包
    hdu3613 扩展KMP
    hdu4333 扩展KMP
    扩展KMP
    hdu4287 字典树
  • 原文地址:https://www.cnblogs.com/yuzhoumanwu/p/8537381.html
Copyright © 2020-2023  润新知