1. 程式人生 > >C# Static初始化順序

C# Static初始化順序

先看個例子:

using System;

Class A
{
 static int X;
 static A()
 {
  X = B.Y + 1;
 }
}

Class B
{
 public static int Y = A.X + 1;
 static B() {}
 
 static void Main()
 {
  Console.WriteLine("X={0},Y={1}",A.X,B.Y); 
  }

}

執行結果是X=1,Y=2

這個例子主要考查2個方面,一是static的用法,二是static的初始化順序。瞭解了static的初始化順序和規則,這個問題答答案就很容易理解了。這裡涉及到以下三類static物件:static成員,static方法,static建構函式。規則如下:

一個類的static建構函式在給定的應用程式域中僅執行一次。static建構函式由在應用程式域的下列事件的首次發生時觸發:
1)該類的例項被建立。
2)任何一個static成員被引用
3)如果類包含執行入口Main方法,此類的static建構函式在Main方法被呼叫之前執行。
4)如果類包含任何staic成員,則這些static成員在static建構函式之前進行初始化。
5)如果類包含任何static方法,則這些static方法在static建構函式之後進行初始化。
6)對於存在多個static成員,他們的初始化將按照文字順序進行,不會因為呼叫順序而改變。

現在看看上面的應用程式,Class B中有個Main執行入口,所以B首先得到初始化,順序是static成員Y->static建構函式。在初始化Y時,引用了A.X,編譯器又開始初始化Class A(注意這時Class B的初始化並沒有完成),順序也是static成員X->static建構函式。Class A中X在定義的時候沒有被賦予初始值(在定義static變數時,儘量賦予初始值),編譯器會預設賦予值0(int型)。然後再執行static的建構函式,由於Class B的初始化這時還沒有完成,所以B.Y的值在這時被編譯器賦予預設值0,所以在A的static的建構函式執行完後,X的值變為1,然後返回B繼續完成初始化,得到Y的值為2。最後執行Main,輸出A.X和B.Y的值。相反地,如果將B中的Main方法移出放在一個類C中,那執行結果又是什麼呢?依據以上的規則,可以很方便的得出答案。

附加說明:
  /// 靜態建構函式是實現對一個類進行初始化的方法成員。
  /// 它一般用於對靜態資料的初始化。
  /// 靜態建構函式只能是私有的,靜態建構函式不能有修飾符
  /// 靜態建構函式不能有引數,不能有修飾符而且不能被呼叫,
  /// 當類被第一次使用的時候,類的靜態建構函式自動被呼叫。
  /// 靜態建構函式只能對靜態資料成員進行初始化,而不能對非靜態資料成員進行初始化。
  /// 靜態方法不能接收到this指標。
  /// 因此他們不能直接訪問類裡的任何例項化資料
  /// 靜態建構函式在IL中表示為cctor(class contructor)

相關推薦

C# Static初始順序

先看個例子: using System; Class A {  static int X;  static A()  {   X = B.Y + 1;  } } Class B {  public static int Y = A.X + 1;  static B(

C++從靜態物件的初始順序理解static關鍵字

問題 首先考慮一個全域性變數的初始化順序問題 在標頭檔案1中: extern int b; int a = b + 1; 在標頭檔案2中: extern int a; int b = a + 1; 原始檔中包含了標頭檔案1和標頭檔案2,這種情況下a和b可能的值是什麼呢? 雖然在開發過程一般不會出現上述這

c++中初始列表的初始變量順序問題

bsp 變量 結果 請問 iostream 類的成員 sin vat 並不是 例題來看:請問下面程序打印出的結果是什麽? 1 #include <iostream> 2 #include <string> 3 4 using namesp

c++ 類成員變數初始順序

#include <iostream> using namespace std; class A { public: //使用初始化列表初始化時,與定義成員變數的順序有關。 //因為成員變數的初始化次序是根據變數在

靜態成員的初始順序(C#,java)

前幾天去參加了場筆試,裡面考了靜態建構函式,當時沒做出來,現在對靜態成員的初始化做一個總結。 在c#類中的靜態成員有靜態變數、靜態函式和靜態建構函式,而在java中是沒有靜態建構函式的,取而代之的是靜態程式塊。靜態成員一般存放在靜態區,而且是屬於類的,所以我們可以不用例項化物件,直接呼叫靜態函式,比如工具

Java基礎4——深入理解final關鍵字和static關鍵字以及初始順序

深入理解final關鍵字和static關鍵字以及初始化順序 final關鍵字(基礎1中提到) final關鍵字可以修飾類、方法和引用。 修飾類,該類不能被繼承。並且這個類的物件在堆中分配記憶體後地址不可變。 修飾方法,方法不能被子類重寫。 修飾引用,引用無法改變,對於基本型別,無法修

C++類成員初始順序問題

今天剛把買了一個月的劍指offer這本書翻閱一下,看到一個簡單的舉例。說應聘C++崗位的不知道成員變數初始化順序!大冬天的背後竟冒出了一絲冷汗,因為我也不知道,所以就上網查了一下,將學到的知識記錄如下。 主要參考部落格: 問題來源: 由於面試題中,

[基礎知識]1.C++成員變數的初始順序

下列程式的執行結果分別是? class A { private: int n1; int n2; public: A():n2(0),n1(n2+2019){} void Print(){ cout << "n1:" << n1 <<

C++派生類物件建構函式初始順序

答:(1)先呼叫基類中的建構函式(如果有多個基類,根據繼承時宣告的順序進行初始化) (2)再呼叫成員類中的建構函式(如果有多個成員類,根據其宣告的順序進行初始化) (3)最後初始化派生類本身的建構函式 例項分析: #include<iostream>   

關鍵字static及物件初始順序

以下內容參考:https://www.cnblogs.com/dolphin0520/p/3799052.html 1.static 變數 靜態變數和非靜態變數的區別: 靜態變數在方法區被所有的物件所共享,在記憶體中只有一個副本,它當且僅當在類初次載入時會

C++成員變數的初始順序問題

問題來源: 由於面試題中,考官出了一道簡單的程式輸出結果值的題:如下, class A { private: int n1; int n2; public: A():n2(0),n1(n2+2){} void Print(){ cout <<

C++類成員變數初始順序問題

今天在看劍指offer這本書時,看待一個簡單的舉例,說應聘C++崗位的不知道成員變數初始化順序!我很驚訝,因為我也不知道,所以就看上網查了一下,看到了一個部落格()以及其中的內容,現在將我的學習過程分

C++中關於全域性物件的初始順序

在stackoverflow上看到下面這樣一個問題: 這個問題很簡單,意思就是兩個全域性不同類的instance,其中一個依賴另一個,怎麼確保他們的構造順序。也就是說O2依賴於o1,o2被例項化之前,我們要確保o1一定要被構造出來,或者說初始化。就上面來看,如果這

C++不同編譯單元內定義的非區域性靜態物件的初始順序

靜態物件是指具有靜態儲存期限的物件,即從定義式開始,分配的記憶體空間一直保留到程式結束的物件,包括全域性變數、定義於名稱空間的物件以及使用static修飾符宣告的物件。靜態物件分為兩類,具有程式塊作用域的static物件稱為區域性靜態物件,其餘的成為非區域性靜態

11.c#類的成員初始順序

using try arc pan 如果 .com 錯誤 自己的 處理 轉自http://www.cnblogs.com/siceblue/archive/2009/01/15/1376430.html C#作為一種純面向對象的話言,為它編寫的整個代碼裏面到處都離不

C#類的初始順序

類的初始化 就是 執行順序 靜態 初始 副本 只有一個 靜態成員 初始化 類在初始化時的執行順序,依次如下: 1: 子類靜態變量 2: 子類靜態構造函數 3: 子類非靜態變量 4: 父類靜態變量 5: 父類靜態構造函數 6: 父類非靜態變量 7: 父類構造函數

多重繼承關系初始順序初始

java 所有 clas 屬性 配對 -- 如果 實現 硬盤 順序:父類屬性--> 父類構造方法--> 子類屬性--> 子類構造方法 初始化: 1.在創建類之前,檢查是否已加載檢查硬盤上的.class是否加載到內存中,如果沒有加載就先加載父類的文件,再加載

Java初始順序(靜態變量、靜態初始塊、實例變量、實例初始塊、構造方法)

靜態初始化 都對 class block 註釋 執行順序 blog 中一 成員變量 1、執行順序 1.1、一個類中的初始化順序 (靜態變量、靜態初始化塊)=>(變量、初始化塊、構造器)。 1.2、兩個具有繼承關系類的初始化順序 父類的(靜態變量、

Java編程思想筆記-類的初始順序

rup cep main mark java boa marker 內存 類的初始化 1、如果有父類,先初始化父類,然後初始化子類 2、先初始化靜態成員變量、靜態代碼塊(static { }包圍的代碼),然後初始化非靜態成員變量、非靜態代碼塊(大括號包圍的代碼)。靜態成員變

C++11 初始列表(initializer_list)

clu amp space return ret 列表 stl容器 int stat C++11對原有的初始化列表(用花括號圍住的若幹個值)進行了大幅的擴展。以下寫法在C++11中都是被允許的: 1 int static_arr[5] = {1, 2, 3, 4};