C#中基类和派生类的构造函数以及变量的执行顺序整理

时间:2021-08-09 19:26:38

  整理了下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      }

  代码中使用了另一个类的静态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

  整理下后得到:

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

  

  结论
  当实例化一个子类时,父类以及子类的变量和构造函数的执行顺序如下:
01子类的静态变量->02子类的静态构造函数->03子类的变量->04父类的静态变量(此时因为要执行子类的构造函数,会与父类发生关系)
->05父类静态构造函数->06父类变量->07父类构造函数->10子类构造函数->结束

  在试验过程里面添加了几个步骤主要说明子类重写父类方法的调用情况:
1)在父类的构造函数中调用(步骤08),此时调用子类的实现时,其中的变量g_a的值还是来自于父类(步骤09)。
2)在调用子类的构造函数后,变量g_a的值被重新设置(步骤11),此时调用子类的实现时,变量值是子类构造函数中设定的。