.ctor,.cctor 以及 对象的构造过程
2012-01-19 11:03
183 查看
.ctor,.cctor 以及 对象的构造过程
.ctor:
简述:构造函数,在类被实例化时,它会被自动调用。
当C#的类被编译后,在IL代码中会出现一个名为.ctor的方法,它就是我们的构造函数,对应C#中的构造函数。且看下面的代码:public class Class1
类Class1中没有显示的构造函数,只有两字段,现在用ILDasm.exe打开编译后生成的exe文件,会看到:
public class Class1
再用ILDasm打开生成的exe文件,打开.ctor,里面有这么几行:
IL_0000: ldarg.0
IL_0001: ldstr "Lin"
IL_0006: stfld string ConsoleApplication1.Class1::name
IL_000b: ldarg.0
IL_000c: call instance void [mscorlib]System.Object::.ctor()
IL_0011: nop
这个跟刚才的相比,多出了红色的那两行,这两行出现在“调用System.Object的构造方法”之前,这说明:
如果在字段声明的同时对其初始化,那么在编译后,赋值过程将被放到构造方法.ctor中,并且在调用其基类的构造方法之前进行。
现在给上面的C#程序显式加上一个构造方法,它接受两个参数:
public class Class1
再用ILDasm打开exe时,会发现有了点变化:
public class Class1
再来打开ILDasm来看看:
public class Class1
再来看看现在ILDasm下的.cctor,其中有几行:
IL_0000: ldc.i4.s 50
IL_0002: stsfld int32 ConsoleApplication1.Class1::count
IL_0007: nop
IL_0008: ldc.i4.s 100
IL_000a: stsfld int32 ConsoleApplication1.Class1::count
可以看到:
如果在声明静态字段时同时对其赋值,它在编译后会被搬到.cctor中,并且是放在前面,然后才到显式定义的静态构造方法体中的代码,也就是说count在这里会被赋值两次,第一次50,第二次100。
在继承中对象构造过程
看下面这段程序:public class A
public class B : A
public class C : B
编译后用ILDasm打开生成的exe文件:
![](http://images.cnblogs.com/cnblogs_com/mouhong-lin/ctor4.jpg)
可以看到三者都有一个.ctor,B、C中有.cctor,而A没有,打开B,C的.cctor,可以看到它们都负责初始化自己的静态字段,现在主要来看它们的.ctor。
先看类C的.ctor:
IL_0001: ldc.i4.3
IL_0002: stfld int32 ConsoleApplication1.C::z
IL_0007: ldarg.0
IL_0008: call instance void ConsoleApplication1.B::.ctor()
IL_000d: nop
IL_000e: nop
IL_000f: ldarg.0
IL_0010: call instance void ConsoleApplication1.C::m3()
可以看到:
在C被实例化时,它最先初始化在声明时同时赋值的字段(非静态),此处是将3赋给z,然后它会调用其基类的.ctor(),然后再调用自己的实例方法m3(),值得注意的是,在执行显式定义的构造方法体中的代码前,会先调用其基类的构造方法(创建基类的实例)。
再来看类B的.ctor():
IL_0001: ldc.i4.2
IL_0002: stfld int32 ConsoleApplication1.B::y
IL_0007: ldarg.0
IL_0008: call instance void ConsoleApplication1.A::.ctor()
IL_000d: nop
IL_000e: nop
IL_000f: ldarg.0
IL_0010: call instance void ConsoleApplication1.B::m2()
同样,我们可以看到,在实例化B时,它会先把2赋给自己的y,然后再调用基类A的构造方法,最后再调用自己的实例方法m2()。
那A的.ctor()就不再看了,可以猜到它一定是在做这样的事:
1、 将1赋给实例的x字段;
2、 调用基类System.Object的构造方法.ctor来创建基类的实例;
3、 调用实例方法m1();
总结
1、.ctor是构造方法;2、.cctor是类型初始化器,在C#中也就是静态构造函数;
3、当类C实例化时,会先对声明时就进行赋值的字段赋值,然后调用基类的构造函数,基类再以同样的方法构造自己,一直到顶层的System.Object,然后再回来执行C的显式构造方法中的代码,就是这么一个递归的过程。
参考资料
1、《Essential .NET》 Volume 1原文:/article/5277496.html
// if ($ != jQuery) {
$ = jQuery.noConflict();
}
var isLogined = true;
var cb_blogId = 33843;
var cb_entryId = 1201747;
var cb_blogApp = "mouhong-lin";
var cb_blogUserGuid = "c42d420b-63cf-dd11-9e4d-001cf0cd104b";
var cb_entryCreatedDate = '2008/5/18 3:38:00';
// ]]>
相关文章推荐
- .ctor,.cctor 以及 对象的构造过程(上)
- .ctor,.cctor 以及 对象的构造过程
- .ctor,.cctor 以及 对象的构造过程
- 构造方法以及对象初始化过程
- 图解Java对象初始化过程以及方法调用
- [JAVA修炼之路四]-JVM内存模型以及对象实例化过程
- 形象解释DC、绘图编制过程以及各个对象、SelectObject()、DeleteObject()
- 前端要给力之:分解对象构造过程new()
- 对象的构造和初始化过程
- Asp.Net运行时对象生成过程以及HttpHandler和HttpModule的处理过程。
- 探索 带有虚函数的单继承的类层次的子类对象的构造过程
- 通过实例学习Java对象的构造过程
- 类的加载、创建对象、静态变量static、构造函数、静态代码块、构造代码块、构造方法以及总结
- 对象和封装以及Java中的构造和重载
- sqlserver2008设置表、存储过程等对象筛选出现“无法为该请求检索数据。 (Microsoft.SqlServer.Management.Sdk.Sfc) ”以及智能提示失效问题
- JSP九大内置对象----以及jsp的编译过程--
- 黑马程序员_对象,构造函数以及构造代码块
- Java中一个对象的构造过程 在 思想永无止境 上转载