- 实例构造器不能被继承,也就是说不能用override,virtual,sealed,abstract,new来修饰
- 如果没有显示的定义构造器,编译器会默认定义一个无参构造器,除非是静态类。
- 创建一个引用类型的实例的过程如下:
- 为这个实例的数据字段分配内存(初始内存为0)
- 初始化对象的附加字段(类型对象指针和同步索引块)
- 调用类型的实例构造器初始化对象的初始状态。(在初始化字段之前所有的字段均为0或者null)
- 在构造器中的字段初始化
class Father { public Father() { MethodFather(); } public virtual void MethodFather() { Console.WriteLine("FatherMethod"); } } class Son : Father { int ss = 10; double dd = 2.3; public Son() { //dd = 12; } public Son(string s) { dd = 13; } public override void MethodFather() { Console.WriteLine("SonMethod"); } }
IL代码如下 :
这是无参构造器的IL代码,如上所示,在构造器中会先初始化两个字段值,然后再调用父类构造函数。
这是有参构造函数:
也是先初始化字段值,然后调用父类构造函数,不同的是,最后会执行自己定义的其他的代码(此处是覆盖dd的值) .
注意:每个构造函数都会初始化字段值和调用父类的无参构造函数。但是,对于某些初始化参数是一致的构造函数,如果在每个构造函数中初始化字段值,然后调用父类构造函数,这样其实是不合理的。其实。可以考虑创建单个的构造器来执行这些公共的初始化,然后,让其他构造器显示调用这个公共初始化构造器,这样可以减少生成的代码。
如下是改进的Son类代码:
class Son : Father
{
int ss = 10;
double dd = 2.3;
public Son()
{
//dd = 12;
}
public Son(string s):this()
{
dd = 13;
}
public override void MethodFather()
{
Console.WriteLine("SonMethod");
}
}
生成的IL代码如下:
无参构造函数的不变的。
有参构造函数分析如下:
此时,有参构造中的字段初始化和父类无参构造的调用没有了(之前的前两步).只是多了一个无参构造的调用,然后,跟之前的一样,执行有参构造中自己的代码(初始化dd字段)