不管學習那門語言都要學習函數體,C#,JAVA,PHP,都會涉及到函數體,而C#的函數體成員並很多,方法和構造器就是函數體成員之一,函數體成員還包括但不限於:方法,屬性,構造器,終結器,運算符及索引器。html
方法就是某個類相關的函數,也能夠返回簡單的基元類型或者什麼也不反回,方法能夠定義其公開性,若是使用static修飾符則變爲靜態方法。c#
屬性是能夠從客戶端訪問到的函數組,訪問形式和訪問類相同,C#爲讀寫類中的屬性提供了專用語法。數組
構造器是實例化對象時自動調用的特殊函數,必須與所屬的類同名,且不能有返回類型,構造器用於初始化字段的值,可經過不一樣參數進行重載。安全
終結器相似與構造函數,可是CLR檢測到再也不須要某個對象時調用他,他的名稱與類相同,但前面有一個~符號 併發
運算符執行的最簡單操做就是「+’「-’「*’「/’這些基本運算,C#也支持重載運算符ide
索引器容許對象以數組的或集合的方式進行索引。函數
構造器性能
以上就是函數體的基本成員和方法的基本定義,接下來咱們先說一下構造器,爲何說構造器?學習
由於構造器實際上會幫咱們很好的理解方法一個類的初始化過程,咱們會發現不管是一個對象實體或是方法,大部分都會放在cs文件中,而構造器是初始化對象的,我創建了一個Student的類裏面只有一個字段一個函數體,在Main函數中我初始化了Student類,運行就會發現構造器函數以及執行,而且調用了方法writethis
能夠發現,當建立一個類型的實例時:
1)爲實例的字段分配內存。
2)初始化對象的附加字段(類型對象指針和同步塊索引)。
3)調用類型的實例構造器來設置對象的初始狀態。
運行後輸出的結果
實例構造器永遠不能被繼承。
由於實例構造器不能被繼承,類只有類本身定義的實例構造器,因此就不能用virtual,new,override,sealed,abstract修飾符來定義構造器。 類型構造器能夠用於接口(C#不容許這樣作),引用類型,值類型。實例構造器用來設置一個類型某個實例的初始化狀態,類型構造器用來設置一個類型的初始化狀態。默認狀況下,若是定義的類沒有顯式的定義一個構造器,編譯器會默認的定義一個無參的構造器。在默認構造器的實現中,它只是簡單的調用了基類的無參構造器。
當咱們在值類型裏面定義了一個類型構造器時,CLR不必定會調用這個靜態構造器,例子建立的是無參類構造器,會在第一次初始化時建立,因此咱們再次實例化stu的時候,控制檯會輸出「我是函數方法1」,若是一個類構造器的方法裏,引入了其餘類型定義了類型構造器,JIT會檢測是否已經在AppDomain裏面執行過。若是沒有執行,則發起對類型構造器的調用,不然不調用。
當程序運行後,線程會開始執行並最終獲取調用構造器的代碼。實際上有可能會是多個線程執行同一個方法,CLR想要確保一個類型構造器在一個AppDomain裏面只執行一次,當一個類型構造器被調用時,調用的線程會獲取一個互斥的線程同步鎖,這時若是有其餘的線程在調用,則會阻塞。當第一個線程執行完後離開,其餘的線程被喚醒並發現構造器的代碼執行過了,因此不會繼續去執行了,從構造器方法返回。CLR經過這種方式來確保構造器僅僅被執行一次。
提示:
因爲CLR會確保類型構造器在每個AppDomain裏面只會執行一次,是線程安全的。因此若是要初始化任何單例對象(singleton object),放在類型構造器裏面是再合適不過了。
靜態構造器
靜態構造函數是實現對一個類進行初始化的方法成員. 它通常用於對靜態數據的初始化. 靜態構造函數不能有參數,不能有修飾符並且不能被調用,當類被加載時,類的靜態構造函數自動被調用.
在一個程序的執行過程當中,靜態構造器最多隻執行一次.
靜態構造器在類的靜態成員初始化以後執行.或者說編譯器會將靜態成員初始化語句轉換成賦值語句放在靜態構造器執行的最開始.
靜態構造器在任何類的靜態成員被引用以前執行.
靜態構造器在任何類的實例變量被分配以前執行.
類型構造器性能
調用類型構造器並不那麼簡單,JIT編譯器不得不決定是否生成調用它的代碼,而且CLR要確保調用是線程安全的。當編譯器決定發起一個調用來執行類型構造器,它必須判斷是否應該這樣作,有兩種可能性:
1.JIT在建立類型的第一個實例的代碼以前當即發起或者在訪問類的非繼承的字段,成員的代碼以前當即調用
2.JIT在首次訪問一個靜態字段,靜態方法,實例方法,或調用一個實例構造器的代碼以前某個時間調用,由於CLR要確保靜態構造器在其餘成員被訪問以前運行。
構造函數中,還有一個特殊的存在, readonly
關鍵字是一個可在字段上使用的修飾符。 當字段聲明包括 readonly
修飾符時,該聲明引入的字段賦值只能做爲聲明的一部分出現,或者出如今同一類的構造函數中。
能夠說
readonly通常只在構造器初始化的時候賦值,其他的時候不能改變他的值。
擴展方法
c# 擴展方法出來已久,介紹擴展方法的文章也不少,簡單點說就是能夠在不改變現有類的狀況下給這個類添加方法。我以爲擴展方法的最大意義在於咱們能夠給那些咱們根本沒法修改的類,好比String,添加咱們自定義的方法。既然沒法經過修改來添加,那就只能經過擴展了。在使用擴展方法時,能夠像調用實例方法那樣調用靜態方法。這就很大程度的方便了代碼的開發。
(1).C#只支持擴展方法,不支持擴展屬性、擴展事件、擴展操做符等。
(2).擴展方法(第一個參數前面是this的方法)必須在非泛型的靜態類中聲明,擴展方法必須有一個參數,並且只有第一個參數使用this標記。
(3).C#編譯器查找靜態類中的擴展方法時,要求這些靜態類自己必須具備文件做用域。
(4).C#編譯要求「導入」擴展方法。(靜態方法能夠任意命名,C#編譯器在尋找方法時,須要花費時間進行查找,須要檢查文件做用域中的全部的靜態類,並掃描它們的全部靜態方法來查找一個匹配)
(5).多個靜態類能夠定義相同的擴展方法。
(6).用一個擴展方法擴展一個類型時,同時也擴展了派生類型。
擴展方法不易亂用,尤爲是在基類中擴展,其全部派生類都會有這個方法,很容易形成不該該出現的地方出現,另外擴展方法必須爲頂級類,不能在嵌套類中使用擴展方法。擴展方法能夠擴展不少種類型,包括但不限於,擴展委託,枚舉,接口。
因爲擴展方法能夠在不少.netformwork提供的類庫上使用擴展方法,例如:Enumerable,Queryable,String等等,也能夠用於擴展異常方法,擴展枚舉。本文篇幅有限,因此咱們舉其中一個示例。咱們寫一個以下的String擴展類,string是c#裏面最最經常使用的類,和它的使用頻度比起來,它的操做確少的可憐,實例方法只有三十個左右,靜態方法只有十多個,
首先咱們把string類最經常使用的靜態方法IsNullOrEmpty擴展成「實例」方法:
只須要創建一個新的靜態類,而後寫一個方法名,將須要擴展的類參數前加上this就能夠了。
在調用的時候,就能夠直接把靜態方法IsNullOrEmpty擴展成「實例」方法來調用。是否是就方便了不少,這只是一個拋磚引玉的例子。
在這裏推薦一篇博文,博文裏講了不少具體的方法實例。
http://www.cnblogs.com/ldp615/archive/2009/08/07/1541404.html