当C#的类被编译后,在IL代码中会呈现一个名为.ctor的办法,它就是我们的机关函数,对应C#中的机关函数。且看下面的代码:
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ret 上方就是这个.ctor的办法体,看上方的红色行,从字面上可以看出,它是调用(call)了一个类型为System.Object的实例的.ctor()办法,从这就可以证实: 当一个类没有显示声明持续于其它某个类时,它将默认持续自System.Object,并且,在类的机关函数中将会调用其基类的机关办法(.ctor)。 如今对上方的法度小改一下,在声明name时对其初始化:
再用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#法度显式加上一个机关办法,它接管两个参数:
再用ILDasm打开exe时,会发明有了点变更: 这里的.ctor带了两参数,一个string类型,一个int32类型,而刚才的无参无返回值的.ctor不见了,这也证了然: 若是类中有显式定义机关办法,那么就不会再主动生成一个无参数无返回值的默认机关办法。 打开.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 从上方红色标识的代码的次序中,我们可以进一步获得: 若是在声明字段时同时对其赋值,那么这个赋值过程将在类型的机关办法(.ctor)中最先履行,然后再履行其基类的机关办法,最后才轮到我们显示定义的机关办法体中代码。
IL_0002: stsfld int32 ConsoleApplication1.Class1::count 它对静态字段count进行了赋值,值是50,那么,是.cctor先调用还是.ctor先调用呢?当然是.cctor,它是为初始化类型而生的,专搞静态的东东,而.ctor是机关办法,当然.cctor要先调用了。 如今显示加上一个.cctor,在C#中就是加个静态机关函数,我们不克不及为其指定接见润饰符(不然编译就会报错):
再来看看如今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。
看下面这段法度:
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()
IL_0001: ldc.i4.2
IL_0002: stfld int32 ConsoleApplication1.B::y
IL_0008: call instance void ConsoleApplication1.A::.ctor()
IL_0010: call instance void ConsoleApplication1.B::m2()
1、.ctor是机关办法; 2、.cctor是类型初始化器,在C#中也就是静态机关函数; 3、当类C实例化时,会先对声明时就进行赋值的字段赋值,然后调用基类的机关函数,基类再以同样的办法机关本身,一向到顶层的System.Object,然后再回来履行C的显式机关办法中的代码,就是这么一个递归的过程。
1、《Essential .NET》 Volume 1
原文:http://www.cnblogs.com/mouhong-lin/archive/2008/05/18/1201747.html