.ctor,.cctor 以及 对象的构造过程
.ctor,.cctor 以及 对象的构造过程.ctor:简述:构造函数,在类被实例化时,它会被自动调用。当C#的类被编译后,在IL代码中会出现一个名为.ctor的方法,它就是我们的构造函数,对应C#中的构造函数。且看下面的代码: ![]() ![]() ![]() ![]() ![]() ![]() 类Class1中没有显示的构造函数,只有两字段,现在用ILDasm.exe打开编译后生成的exe文件,会看到: ![]() 可以看到这里有个.ctor,我们没有定义构造函数,但这里却出现了.ctor,这就说明了: 当没有显示定义构造函数时,会自动生成一个构造函数,它没有参数,没有返回值。 那我们来看看这个.ctor都干了什么吧,双击.ctor打开,在弹出的窗口中可以找到下面的几行代码: IL_0000: ldarg.0 IL_0001: call instance void [mscorlib]System.Object::.ctor() IL_0006: ret ![]() ![]() ![]() ![]() ![]() ![]() 再用ILDasm打开生成的exe文件,打开.ctor,里面有这么几行: 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 ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() 再用ILDasm打开exe时,会发现有了点变化: 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 IL_0012: nop IL_0013: ldarg.0 IL_0014: ldarg.1 IL_0015: stfld string ConsoleApplication1.Class1::name IL_001a: ldarg.0 IL_001b: ldarg.2 IL_001c: stfld int32 ConsoleApplication1.Class1::age IL_0021: nop .cctor简述:类型初始化器,是一个静态方法,无参数无返回值,不能直接调用,最多只有一个我们现在先给刚才的代码加上一个静态字段:![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() 再来打开ILDasm来看看: ![]() 发现这里多了一个.cctor,它就是类型初始化器,打开它,会看到其中有一句: IL_0000: ldc.i4.s 50 IL_0002: stsfld int32 ConsoleApplication1.Class1::count ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() 再来看看现在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 可以看到: 在继承中对象构造过程看下面这段程序: ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() 编译后用ILDasm打开生成的exe文件: ![]() 可以看到三者都有一个.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() 那A的.ctor()就不再看了,可以猜到它一定是在做这样的事: 1、 将1赋给实例的x字段; 2、 调用基类System.Object的构造方法.ctor来创建基类的实例; 3、 调用实例方法m1(); 总结1、.ctor是构造方法; 参考资料1、《Essential .NET》 Volume 1 原文:http://www.cnblogs.com/mouhong-lin/archive/2008/05/18/1201747.html |
posted on 2013-07-12 14:19 jian60521 阅读(8034) 评论(0) 编辑 收藏 举报