[Clr via C#读书笔记]Cp5基元类型引用类型值类型

时间:2023-03-09 01:22:27
[Clr via C#读书笔记]Cp5基元类型引用类型值类型

Cp5基元类型引用类型值类型

基元类型

编译器直接支持的类型,基元类型直接映射到FCL中存在的类型。
作者希望使用FCL类型名称而避免使用关键字。他的理由是为了更加的清晰的知道自己写的类型是哪种。但是实际当中关键字更常用,FCL类型的写法太繁琐了。特别是你不用过多考虑和其他语言交互的时候,只使用C#的时候。所以这一点上我还是不同意作者的看法。
类型的隐式转换和显示转换过程中的可能存在的问题。checked,unchecked;来检查溢出;
CLR并不认为Decimal是基元类型,所以执行速度要慢很多。

引用类型和值类型

引用类型在托管堆上创建,new后返回其在托管堆上的地址,受GC控制,引用变量还是在栈上,用来存储引用,没有的时候存的就是null。
而值类型则在线程栈上创建,其保存的就是值本身而不是地址,不受GC控制。结构,枚举,派生自System.ValueType,全都是Sealed。
Struct使用new的目的和引用类型不同,是为了初始化内部成员,如果不使用new来初始化内部成员,也可以使用对象.成员的方式一个一个设置,就是比较麻烦。可以给Struct设置一个带参数的构造函数,这个构造函数的目的也是为了初始化内部成员,不是为了创建结构。
可空类型nullable
值复制会复制值本身,引用复制只会复制引用;

装箱和拆箱

装箱和拆箱的含义这一块很好理解。 装箱拆箱影响性能,所以尽量避免。要会分析给定代码的装箱拆箱次数。大多数方法进行重载的唯一目的是为了减少装箱拆卸操作。

  • 对没有装箱的值类型(主要是说Struct),直接调用虚方法。
  • 重写的虚方法调用方法在基类中的实现,那么该值类型会被装箱,以便通过this指针引用对一个堆对象的引用传递给基方法。
  • 调用非虚的继承自Object的的方法需要装箱,因为需要的this指向的是堆上的实例的引用 。
  • 将值类型未装箱的实例传递给接口的时候,会装箱,因为接口对应的是引用。
    书上这里写的也比较绕口,具体参考P122的例子,例子和例子的解释都非常的清楚。
    C#不允许更改已装箱的值。

相等性和同一性

Equals方法=同一性identity;重写Equals;静态方法ReferenceEquals;
接口System.IComparable,System.IComparable,CompareTo方法

对象HashCode

两个对象相等,必须要有相同的hashcode.

dynamic基元类型

本质就是Object。
动态化显著简化了COM对象互操作。
C#的动态支持会产生大量开销,所以使用的时候要考虑清楚。