C# 實例化的執行順序(轉)

首先進行細分
1.類的成員分爲:字段,屬性,方法,構造函數
2.成員修飾符:靜態成員,實例成員
不考慮繼承的關係執行順序爲:
1.靜態字段
2.靜態構造方法
3.實例字段
4.實例構造方法
其中 屬性和方法只有在調用的時候才執行。
下面是一段代碼例子:ide

 class Test
        {
            public static int temp;
            public int mNum;
            public int mNum2 = 2;
            public void Look()
            {
                Console.WriteLine("看我,我是test");
                Console.WriteLine("mNum={0}", mNum);
            }
            private int mNum3 = 3;
            private readonly int mNum4 = 4;
            public int Num3
            {
                get { return mNum3; }
                set { mNum3 = value; }
            }
            public Test()
            {
                temp = 1;
                mNum = 0;
            }
        }

定義了一個類,當咱們實例化的時候
Test test = new Test();
 執行過程是:
0. 靜態的最早執行,仿真編譯略過
1. F11 執行 public int mNum2=2; //簡單的初始化字段
2. private int mNum3 = 3;
private int mNum4 = 4;
3. public Test() { temp = 1;mNum = 0; } //構造函數函數

注意:public int mNum;也執行了,只不過系統默認賦值0spa

當存在繼承關係的時候,執行的順序。
1. 子類的靜態字段
2. 子類的靜態構造方法
3. 子類的實例字段
4. 父類的靜態字段
5. 父類的靜態構造方法
6. 父類的實例字段
7. 父類的實例構造方法
8. 子類的實例構造方法code

 class A : Test
        {
            readonly int x = 1;
            public A()
            {
                PrintFields();
                Look();
            }

            readonly int c;
            readonly int sd = 6;
            public virtual void PrintFields()
            {
                Console.WriteLine("j={0},k={1}", "AA", "AA");
            }
        }
        class B : A
        {
            readonly int y;
            int z = 2;
            public B()
            {
                z = -1;
            }
            public override void PrintFields()
            {
                Console.WriteLine("x={0},y={1}", "b", z);
            }
        }
        class C : B {
            int x = 1;
            int y = 3;
            public override void PrintFields() {
                Console.WriteLine("j={0},k={1}", "CC", y);
            }
        }


        static void Main(string[] args)
        {
            Console.WriteLine("======實例化Test======");
            Test test = new Test();
            Console.WriteLine("======實例化A======");
            A a = new A();
            Console.WriteLine("======實例化B======");
            B b = new B();
            Console.WriteLine("======實例化C======");
            C c = new C();
            Console.ReadKey();
        }

1. 首先執行 class A中 int x = 1;,執行全部已經初始化後的字段,當執行到構造函數首執行父類字段blog

2. int sd = 6;繼承

3. public A(),首先會去執行父類。get

4. 0. 靜態的最早執行,仿真編譯略過 1. F11 執行 public int mNum2=2; //簡單的初始化字段 2. private int mNum3 = 3; private int mNum4 = 4; 3. public Test() { temp = 1;mNum = 0; } //構造函數string

5. public A() { PrintFields(); look(); }// 執行子類中本身的構造函數it

6. public virtual void PrintFields() ;執行本身類中有意義的虛函數編譯

7. 執行調用父類的函數 look();

8. 接下來就將要執行 class B 中的內容了。過程相似,先一步一步的執行A類,在執行Test類,實現繼承。

9. 忽略部分細節,降調B類中的細節。

int z=2;

public B() 運行到這裏的時候,再次執行到 public A() { PrintFields(); look(); } 的構造函數的時候,因爲執行的是實例化B類,又在B類中重寫了PrintFields();,實現多態。

因此執行 public override void PrintFields() { Console.WriteLine("x={0},y={1}", "b", z); } 因此此時的 z=2; 而不是 public B() { z = -1; } 中的z=-1,由於尚未執行到它,隨後才執行子類中的構造函數。

相關文章
相關標籤/搜索