-
实例构造器和类(引用类型)
三步曲:
a.分配内存(分配的内存是0或者null前几篇介绍过)
b.初始化对象(初始化套餐--套餐定义见前面几章) c.调用基类构造器
一个类会默认有一个构造器,不自定义系统就帮你定义,为啥呢?因为要初始化对象啊不让程序没法运行,除非微软粑粑改了初始化的机制和地方。前几篇开篇讲了一些基本的调用。
因此在内联字段带来的性能问题就是:会在每个构造器重插入该字段的初始化代码(系统生成的)一个优化的做法就是外面只定义,构造器中再初始化。temp_fields2的示例
因此构造器多了、内联字段多了性能就受到影响了。
构造器的调用顺序:先基类后子类因此一些虚方法、GC.SuppressFinalize等需要指定在本类中执行的一些机制函数,不适合在构造器中执行。为啥呢?
虚方法:被实例化的类型重写了虚方法后,会先调用派生类的虚方法的实现的虚方法。但是此时还未完成对继承层次中的所有字段的初始化(被实例化的构造器还没运行),因此以上看出虚方法的执行顺序是不确定的。这是因为虚方法的特性,只有在确实执行之前才能确定其类型,从而执行。(看缘分吧这段比较难以理解)主要是对虚方法的执行机制要非常清楚。
GC.SuppressFinalize :因为如果在父类构造器也执行 GC.SuppressFinalize 时候出错了那么,该构造器中该方法必然出错。详情后续会讲。因此一些新手甚至是工作10几年的大神应该也会在这块犯错。
2.值类型的构造器
C#不允许值类型有无参数构造器,但是CLR允许。不做深究没啥实际意义。
3.类型构造器
隐式模式私有静态。
构造过程:静态构造函数是线程安全的。这个在JIT构造过程中就体现出来,CLR仅仅允许每个静态构造器被执行一次。做法是保证机制是首次到达的线程获取一个互斥线程锁。防止其他线程再次执行。
并且静态构造器中初始化的是静态的、其分配在三个域一个堆中的 默认域 Appdomain域中。
虽然可以在值类型中定义类型构造函数,然而实际上因为值类型根本就不会在堆中有类型对象,所以自然里面的代码都不会被调用。
4.转化操作符、重载操作符(个人认为平时用的少不做介绍要是谁想用自己百度下,本系列也仅仅从实际开发中出发,谈一些个人对C#和运行机制的理解,对实际生产编码影响不大的不常用的技巧一般不做介绍)
5.扩展方法
顶级非泛型静态类中定义,参数+this ,仅仅支持扩展方法。属性事件等你能想到的都不支持。
6.分部方法
一个类太大,分为几个文件些名字相同,修饰符是 partial ,要求部方法返回值是void,任何参数无 out修饰,分部方法隐式private