c 靜態建構函式

2021-05-25 23:54:22 字數 3232 閱讀 2104

c#靜態建構函式,又稱類建構函式。它是屬於類的,不屬於任何乙個類的例項。它具有以下特點:

1、以static定義的,無訪問修飾符,無返回型別,無引數的建構函式,如: 

code:

class test   

}  2、不能通過**顯式的呼叫靜態建構函式

3、靜態建構函式在類的靜態成員第一次訪問或第乙個類例項建立之前由系統呼叫

4、靜態建構函式最多執行一次

5、靜態建構函式須顯式定義,若不定義,則不存在預設靜態建構函式:此特點後面將詳細說明

6、乙個類中最多只能定義乙個靜態建構函式

7、靜態建構函式主要完成的是靜態資料成員的初始化工作,若定義靜態資料成員的時候進行初始化,同時在靜態建構函式中進行了初始化,則以靜態建構函式的初始化為準。 

code:

c#**:

class test   

}   

il**:   

.class

private auto ansi test   

extends [mscorlib]system.object   

.method public hidebysig specialname rtspecialname instance void .ctor() cil managed   

.field public

static

string x   

}   

從上面的c#轉換為il**可以看出,x被賦值了兩次,一次是a,一次是b,但是最後起作用的是b。

對於靜態建構函式,很多的介紹中都認為存在預設的靜態建構函式,我個人認為這是不準確的。因為很多人都認為靜態建構函式和轉換的il**中的.cctor方法是對應的。其實不然,.cctor可以說是靜態成員初始化器或是類初始化器,但並不是所有的類在轉化成il**的時候都會生成.cctor方法;而靜態建構函式會影響.cctor生成的**,同時會通過取消il**中的"beforefieldinit"而影響.cctor方法的呼叫時機。下面就分別從幾個類生成的il**情況,對問題進行說明。

1、無靜態建構函式、靜態成員的空類:有beforefieldinit標記,無.cctor函式 

code:

c#**:   

class test   

轉化的il**:   

.class

private auto ansi beforefieldinit test   

extends [mscorlib]system.object   

}   

2、無靜態建構函式、有靜態成員但宣告時未進行初始化:與1的結果一樣有beforefieldinit標記,無.cctor函式 

code:

c#**:   

class test   

轉化的il**:   

.class

private auto ansi beforefieldinit test   

extends [mscorlib]system.object   

.field public

static

string x   

}   

3、無靜態建構函式、有靜態成員並已初始化:有beforefieldinit標記、有.cctor函式

code:

c#**:   

class test   

轉化的il**:   

.class

private auto ansi beforefieldinit test   

extends [mscorlib]system.object   

.method public hidebysig specialname rtspecialname instance void .ctor() cil managed   

.field public

static

string x   

}   

4、有靜態建構函式、無靜態成員的類:無beforefieldinit標記、有.cctor函式

code:

c#**:   

class test   

}   

轉化的il**:   

.class

private auto ansi test   

extends [mscorlib]system.object   

.method public hidebysig specialname rtspecialname instance void .ctor() cil managed   

}   

通過上面的分析,可以了解:無靜態建構函式的時候,類生成的il**中一定有beforefieldinit標記,但不一定有.cctor函式;有靜態建構函式的時候,生成的il**中必定有.cctor函式,類中無beforefieldinit標記;.cctor函式是負責靜態成員的初始化的,如果宣告時和在靜態建構函式中都有初始化,則兩者會合併到.cctor函式中,宣告的初始化在前,靜態建構函式的初始化在後。

beforefieldinit標記主要是用來決定.cctor呼叫時機。

如果未宣告類的靜態建構函式,則會設定beforefieldinit標記,此時的.cctor函式會交給clr進行呼叫,clr可以選擇程式集載入到第一訪問型別(包括訪問靜態成員和類例項)的這個時間段內的任何時間點呼叫.cctor函式,此時較難掌握.cctor執行時機。

如果宣告了類的靜態建構函式,則將不設定beforefieldinit標記,此時.cctor是在第一次使用類之前呼叫,可以順利跟蹤具體的時機。

以上兩種方式在速度上存在較大的差別,其中設定了beforefieldinit標記的類,在型別初始化器(.cctor)的執行效能上優於未設定beforefieldinit的類。具體可參考:

靜態建構函式在效能上不如未設定靜態建構函式的情況,那為什麼還是建議大家使用靜態建構函式初始化各類靜態成員呢?個人認為,主要是通過靜態建構函式,可以很好的把握初始化靜態成員的時機,雖然在效能上有點劣勢,但是因為只初始化一次,這點效能上的影響微乎其微。可以不予考慮。可參看effective c#原則13

C 靜態建構函式

c 靜態建構函式 靜態建構函式是 c 的乙個新特性,在程式設計過程中用處並不廣,它的主要目的是用於初始化一些靜態的變數。因為這個建構函式是屬於類的,而不屬於任何乙個例項,所以這個建構函式只會被執行一次,而且是在建立此類的第乙個例項或引用任何靜態成員之前,由 net 自動呼叫。在程式中我們可以這樣寫 ...

C 靜態建構函式

c 靜態建構函式 duduhe譯 簡介 net c 提供靜態建構函式功能,用以初始化靜態資料及執行某項特殊操作,該操作可能僅需執行一次。靜態建構函式用如下格式來宣告 static classname 以下任意情況發生時,靜態建構函式自動呼叫 l類例項的建立。l類的任意乙個靜態成員 屬性或方法 被呼叫...

C 靜態建構函式

對於c 靜態建構函式,很少在開發中使用,但的確是一種非常有用的開發方式。c 靜態建構函式的乙個重要原因是 類有一些靜態欄位或屬性,需要在第一次使用該類之前,從外部源中初始化這些靜態字段或者屬性。用下面的例子來說明靜態建構函式的使用 namespace staticconstructorsample ...