靜態建構函式與靜態變數

2021-05-22 23:07:37 字數 3240 閱讀 8331

靜態建構函式

c#物件初始化1.

先變數後建構函式。變數先被初始化 ,然後建構函式被執行 2.

先靜態化後例項化。

當 乙個類被訪問時

,靜態變數和建構函式最先被初始化 .接著是物件的例項化變數和建構函式被初始化

3.先派生類後基類。對於變數和靜態建構函式 ,派生物件在基物件之前被初始化 .比如 c類派生自 b類 ,b類派生自 a類 ,那麼變數和靜態建構函式被初始化次序是 c-b-a. 4.

除了例項建構函式。對於例項建構函式 ,基類建構函式在派生類建構函式之前執行 ,例項建構函式被執行次序是 a-b-c. 5.

不要假定變數的次序。 fields依據它們在原始檔中的宣告的順序依次初始化 .然而 ,自從程式設計師和工具可以隨意安排變數的宣告後 ,你不應該在依靠變數任何特別的次序初始化 6.

對虛方法用兩個階段的構建。避免從乙個構造器呼叫虛方法 .如果在初始化乙個物件時需要呼叫一些虛方法 ,應在完整構造該物件的地方使用兩階段的構建,並隨後呼叫已構造物件的初始化方法。

先來看乙個經典題目:

class a

}class b

static void main()

,y=", a.x, b.y);}}

問的是輸出的結果是什麼,也就是main()裡面 a.x, b.y的值

這個題目的答案是 1,2

為什麼呢?

因為執行的時候,首先從程式的入口點(就是main())找起,因為main在類b中,所以從b類開始載入。執行順序大致是這樣的:

(用到乙個類的時候是先對其靜態變數初始化,然後呼叫他的靜態建構函式)

(類的靜態建構函式只在載入類的時候由系統呼叫一次且只此一次)

1.初始化b類的靜態變數 y,系統先給他乙個預設值(此處是0),然後再執行他的初始化賦值語句public static int y =a.x+ 1;

2.執行這條語句的時候因為用到了a.x,所以遇到a的時候去載入類a,順序一樣,先是執行a的靜態變數x的初始化工作public static int x;因為沒有對其賦值的操作,所以x就是系統給他的預設值0;然後呼叫a的靜態建構函式(b那裡也是先初始化靜態變數,然後才呼叫靜態建構函式,因為b初始化靜態變數的時候用到了a所以才會跳到a來,不然的話b那邊也是初始化靜態變數之後系統緊接著就會呼叫b的靜態建構函式);

3,a的靜態建構函式中執行x =b.y+ 1;可以知道,此時b.y已經有了乙個系統給他的預設值0,所以此處就是x=0+1;現在x就是1了

4,x那邊都完工了,回到剛才跳轉x的地方繼續執行,就是繼續執行y = a.x + 1;毫無疑問此時是y=1+1;至此,b的靜態變數初始化完成了。

5,b的靜態變數初始化完成了那緊接著就是系統呼叫b的靜態建構函式,此處什麼也不執行。

6.輸出結果1,2

總結一下:

1、這種東西總歸就是執行的時候,main在哪個類裡面就先初始化哪個類(如果main在外邊,比如main不在a,b中,那麼看main先用到誰就先初始化誰 );

2、然後初始化的時候,在載入類的時候是先初始化類的靜態變數,然後接著執行類的靜態建構函式(靜態建構函式是載入類的時候系統呼叫的,只執行這一次。);

3、初始化靜態變數的時候,系統先給他賦上預設值,然後才執行類中定義的賦值語句,比如public static int 

z = 3;實際上是先是z=0;然後z=3;

4、初始化完了靜態變數之後緊接著呼叫此類的靜態建構函式(上面的那個例子也是按照這個順序的,有人可能問為什麼上面那個例子b靜態變數初始化的時候有跳 轉,其實那也是完全按照順序執行,因為b順序是現初始化靜態變數,然後靜態建構函式。可是b靜態變數初始化的時候用到了a,那a就也是靜態變數-構造函 數,然後回到b靜態變數初始化的語句繼續執行,b靜態變數初始化完了才緊接著b靜態建構函式。)

5、看看下面幾個例子,全都做對了就說明你掌握了

using system;

class a

static void main(string args)

/tb.y:", a.x, b.y);

console.read();}}

class b}

上面這個例子的結果是什麼呢???

他的執行順序應該是

1、public static int x;

2、static a()

3、public static int y = a.x + 1;

4、static b();

沒錯,結果就是 2,1

再看下面的乙個

using system;

class a }

class b}

class c

/tb.y:", a.x, b.y);

console.read();}

} 結果是什麼呢?

他的執行順序應該是

1、public static int x;

2、static a()

3、public static int y = a.x + 1;

4、static b();

沒錯,結果還是 2,1,因為先用到的a後用到的b嘛!

分析此類問題,只要記住三點就行了。

第一**的執行順序,**在前的先執行;

第二靜態成員初始化語句要先於靜態建構函式執行;

第三靜態成員初始化語句與靜態建構函式只執行一次。

靜態變數 靜態屬性 靜態建構函式

靜態屬性不屬於任何例項,也是屬於類的,和靜態變數不同的是,只用在呼叫它的時候,才會初始化,而且每次呼叫都會重新賦值。靜態建構函式需用static修飾,但不能用public或private等關鍵字修飾,因為靜態建構函式不能直接呼叫,無論是直接例項化還是通過class.method的方式。下面我們看看在...

非靜態函式,非靜態變數與靜態函式,靜態變數

一 函式 函式的引入可以減少程式的目標 實現程式 的共享。但是,函式呼叫也需要一些時間和空間方面的開銷,因為呼叫函式實際上將程式執行流程轉移到被調函式中,被調函式的程式 執行完後,再返回到呼叫的地方。這種呼叫操作要求呼叫前保護現場並記憶執行的位址,返回後恢復現場,並按原來儲存的位址繼續執行。對於較長...

非靜態函式,非靜態變數與靜態函式,靜態變數

非靜態函式,非靜態變數與靜態函式,靜態變數 一 函式 函式的引入可以減少程式的目標 實現程式 的共享。但是,函式呼叫也需要一些時間和空間方面的開銷,因為呼叫函式實際上將程式執行流程轉移到被調函式中,被調函式的程式 執行完後,再返回到呼叫的地方。這種呼叫操作要求呼叫前保護現場並記憶執行的位址,返回後恢...