.ctor(下)

.ctor(下)

在继承中对象构造过程

看下面这段程序:

  
 1   public class A
 2     {
 3         public int x = 1;
 4         public A() { m1(); }
 5         public void m1() { }
 6      }
 7 
 8     public class B : A
 9     {
10         public int y = 2;
11         public static string sb = "B";
12         public B() { m2(); }
13         public void m2() { }
14      }
15 
16     public class C : B
17     {
18         public int z = 3;
19         public static string sc = "C";
20         public C() { m3(); }
21         public void m3() { }
22      }

 



编译后用ILDasm打开生成的exe文件:


可以看到三者都有一个.ctor,B、C中有.cctor,而A没有,打开B,C的.cctor,可以看到它们都负责初始化自己的静态字段,现在主要来看它们的.ctor。

先看类C的.ctor:
 1 IL_0001: ldc.i4.3
 2 
 3 IL_0002: stfld      int32 ConsoleApplication1.C::z
 4 
 5 IL_0007: ldarg.0
 6 
 7 IL_0008: call       instance void ConsoleApplication1.B::.ctor()
 8 
 9 IL_000d: nop
10 
11 IL_000e: nop
12 
13 IL_000f: ldarg.0
14 
15 IL_0010: call       instance void ConsoleApplication1.C::m3()

 

 

可以看到: 
在C被实例化时,它最先初始化在声明时同时赋值的字段(非静态),此处是将3赋给z,然后它会调用其基类的.ctor(),然后再调用自己的实例方法m3(),值得注意的是,在执行显式定义的构造方法体中的代码前,会先调用其基类的构造方法(创建基类的实例)。

再来看类B的.ctor(): 
 1 IL_0001: ldc.i4.2
 2 
 3 IL_0002: stfld      int32 ConsoleApplication1.B::y
 4 
 5 IL_0007: ldarg.0
 6 
 7 IL_0008: call       instance void ConsoleApplication1.A::.ctor()
 8 
 9 IL_000d: nop
10 
11 IL_000e: nop
12 
13 IL_000f: ldarg.0
14 
15 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的显式构造方法中的代码,就是这么一个递归的过程。

posted @ 2013-08-30 15:25  Cornelius  阅读(2482)  评论(0编辑  收藏  举报