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、拆箱后如果复制数据到线程栈中,并且修改栈的数据,原堆中的数据不受影响;

posted on 2018-03-10 09:24  时空旅行  阅读(126)  评论(0编辑  收藏  举报