整理了下C#中基类以及派生类的构造函数,变量声明的执行顺序。
先上试验代码:
1
class
Program
2 {
3 static void Main( string [] args)
4 {
5 B b = new B();
6 Console.WriteLine(A.s_a);
7 Console.WriteLine(B.s_b);
8 Console.WriteLine(b.g_a);
9 Console.WriteLine(b.g_a_1);
10 Console.WriteLine(b.g_b);
11 }
12 }
13 // 基类
14 class A
15 {
16 // 静态变量
17 public static string s_a = " A.s_a " + (C.index ++ ).ToString( " _00 " );
18 // 变量
19 public string g_a = " A.g_a " + (C.index).ToString( " _00 " );
20 // 为了显示A.g_a
21 public string g_a_1 = " A.g_a_1 " + (C.index ++ ).ToString( " _00 " );
22
23 // 静态构造函数
24 static A()
25 {
26 Console.WriteLine( " It is in static A() " + (C.index ++ ).ToString( " _00 " ));
27 }
28 // 构造函数
29 public A()
30 {
31 Console.WriteLine( " It is in A() " + (C.index ++ ).ToString( " _00 " ));
32 this .M();
33 }
34 // 虚方法
35 public virtual void M()
36 {
37 Console.WriteLine( " It is in A.M() " + (C.index ++ ).ToString( " _00 " ));
38 }
39 }
40
41 // 派生类
42 class B : A
43 {
44 // 静态变量
45 public static string s_b = " B.s_b " + (C.index ++ ).ToString( " _00 " );
46 // 变量
47 public string g_b = " B.g_b " + (C.index ++ ).ToString( " _00 " );
48
49 // 静态构造函数
50 static B()
51 {
52 Console.WriteLine( " It is in static B() " + (C.index ++ ).ToString( " _00 " ));
53 }
54 // 构造函数
55 public B()
56 : base ()
57 {
58 Console.WriteLine( " It is in B() " + (C.index ++ ).ToString( " _00 " ));
59 g_a += " ->B.g_a " + (C.index ++ ).ToString( " _00 " );
60 this .M();
61 }
62 // 重写方法
63 public override void M()
64 {
65 Console.WriteLine( " It is in B.M() " + (C.index ++ ).ToString( " _00 " ));
66 Console.WriteLine( " B.g_a= " + g_a + (C.index ++ ).ToString( " _00 " ));
67 }
68 }
69 class C
70 {
71 public static int index = 1 ;
72 }
2 {
3 static void Main( string [] args)
4 {
5 B b = new B();
6 Console.WriteLine(A.s_a);
7 Console.WriteLine(B.s_b);
8 Console.WriteLine(b.g_a);
9 Console.WriteLine(b.g_a_1);
10 Console.WriteLine(b.g_b);
11 }
12 }
13 // 基类
14 class A
15 {
16 // 静态变量
17 public static string s_a = " A.s_a " + (C.index ++ ).ToString( " _00 " );
18 // 变量
19 public string g_a = " A.g_a " + (C.index).ToString( " _00 " );
20 // 为了显示A.g_a
21 public string g_a_1 = " A.g_a_1 " + (C.index ++ ).ToString( " _00 " );
22
23 // 静态构造函数
24 static A()
25 {
26 Console.WriteLine( " It is in static A() " + (C.index ++ ).ToString( " _00 " ));
27 }
28 // 构造函数
29 public A()
30 {
31 Console.WriteLine( " It is in A() " + (C.index ++ ).ToString( " _00 " ));
32 this .M();
33 }
34 // 虚方法
35 public virtual void M()
36 {
37 Console.WriteLine( " It is in A.M() " + (C.index ++ ).ToString( " _00 " ));
38 }
39 }
40
41 // 派生类
42 class B : A
43 {
44 // 静态变量
45 public static string s_b = " B.s_b " + (C.index ++ ).ToString( " _00 " );
46 // 变量
47 public string g_b = " B.g_b " + (C.index ++ ).ToString( " _00 " );
48
49 // 静态构造函数
50 static B()
51 {
52 Console.WriteLine( " It is in static B() " + (C.index ++ ).ToString( " _00 " ));
53 }
54 // 构造函数
55 public B()
56 : base ()
57 {
58 Console.WriteLine( " It is in B() " + (C.index ++ ).ToString( " _00 " ));
59 g_a += " ->B.g_a " + (C.index ++ ).ToString( " _00 " );
60 this .M();
61 }
62 // 重写方法
63 public override void M()
64 {
65 Console.WriteLine( " It is in B.M() " + (C.index ++ ).ToString( " _00 " ));
66 Console.WriteLine( " B.g_a= " + g_a + (C.index ++ ).ToString( " _00 " ));
67 }
68 }
69 class C
70 {
71 public static int index = 1 ;
72 }
代码中使用了另一个类的静态int型变量记录下各个部分的执行顺序。
运行结果是:
It is in static B()_02
It is in static A()_05
It is in A()_07
It is in B.M()_08
B.g_a=A.g_a_06_09
It is in B()_10
It is in B.M()_12
B.g_a=A.g_a_06->B.g_a_11_13
A.s_a_04
B.s_b_01
A.g_a_06->B.g_a_11
A.g_a_1_06
B.g_b_03
It is in static A()_05
It is in A()_07
It is in B.M()_08
B.g_a=A.g_a_06_09
It is in B()_10
It is in B.M()_12
B.g_a=A.g_a_06->B.g_a_11_13
A.s_a_04
B.s_b_01
A.g_a_06->B.g_a_11
A.g_a_1_06
B.g_b_03
整理下后得到:
B.s_b_01
It is in static B()_02
B.g_b_03
A.s_a_04
It is in static A()_05
A.g_a_1_06
It is in A()_07
It is in B.M()_08
B.g_a=A.g_a_06_09
It is in B()_10
A.g_a_06->B.g_a_11
It is in B.M()_12
B.g_a=A.g_a_06->B.g_a_11_13
It is in static B()_02
B.g_b_03
A.s_a_04
It is in static A()_05
A.g_a_1_06
It is in A()_07
It is in B.M()_08
B.g_a=A.g_a_06_09
It is in B()_10
A.g_a_06->B.g_a_11
It is in B.M()_12
B.g_a=A.g_a_06->B.g_a_11_13
结论:
当实例化一个子类时,父类以及子类的变量和构造函数的执行顺序如下:
01子类的静态变量->02子类的静态构造函数->03子类的变量->04父类的静态变量(此时因为要执行子类的构造函数,会与父类发生关系)
->05父类静态构造函数->06父类变量->07父类构造函数->10子类构造函数->结束
在试验过程里面添加了几个步骤主要说明子类重写父类方法的调用情况:
1)在父类的构造函数中调用(步骤08),此时调用子类的实现时,其中的变量g_a的值还是来自于父类(步骤09)。
2)在调用子类的构造函数后,变量g_a的值被重新设置(步骤11),此时调用子类的实现时,变量值是子类构造函数中设定的。