新聞中心
本文帶大家一起來學(xué)習(xí)CLR Via C#,主要講述的是關(guān)于CLR Via C# 的構(gòu)造函數(shù),希望大家看完此篇文章感覺到收獲許多。

CLR Via C#中構(gòu)造函數(shù)是可以將類型實例初始化為有效狀態(tài)的特殊方法。構(gòu)造函數(shù)在元數(shù)據(jù)中通常用.ctor來表示,通過IL代碼可以看到。在創(chuàng)建一個類型的實例時,通常分為三步:
1 為實例的數(shù)據(jù)字段分配內(nèi)存。
2 創(chuàng)建對象指針和同步索引塊。
3 調(diào)用類型的實例構(gòu)造器來設(shè)置對象的初始狀態(tài)。
CLR Via C#中引用類型的實例構(gòu)造器
在創(chuàng)建一個引用類型的對象是,調(diào)用類型的實例構(gòu)造函數(shù)之前,會將對象分配的內(nèi)存做清零處理,就是說在構(gòu)造函數(shù)中沒有顯示賦值的所有字段都將設(shè)置為0或null。
實例構(gòu)造函數(shù)和一般方法不同,他永遠(yuǎn)都不能被繼承,所有以下的關(guān)鍵字也不能用于實例構(gòu)造函數(shù)(virtual new override sealed abstract)。
一個類中如果沒有顯示定義任何構(gòu)造函數(shù),C#編譯器將定義一個默認(rèn)的無參構(gòu)造函數(shù)。
抽象(abstract)類的默認(rèn)構(gòu)造函數(shù)的訪問修飾符為protected。
構(gòu)造函數(shù)可以初始化字段,不過在c#語言中提供了一種簡單的方法,在定義字段的時候直接賦值以初始化。如下:
- public class User2
- {
- private int _age = 25;
- private string _name = "oec2003";
- }
像上面那樣的確很方便,但如果有好幾個已經(jīng)初始化的實例字段和多個重載的構(gòu)造函數(shù)同時存在的情況下,就應(yīng)該將實例字段的初始化放到一個公共的構(gòu)造函數(shù)中,其他的構(gòu)造函數(shù)通過this來顯示調(diào)用該構(gòu)造函數(shù),這樣可以減少代碼生成的大小,看下面的例子。
- public abstract class User
- {
- private int _age=25;
- private string _name="oec2003";
- private string _email = "[email protected]";
- public User(Int32 age)
- {
- this._age = age;
- }
- public User(string name)
- {
- this._name = name;
- }
- public User(Int32 age, String name, String email)
- {
- this._age = age;
- this._name = name;
- this._email = email;
- }
正確的寫法應(yīng)該像下面這樣
- public abstract class User
- {
- private int _age;
- private string _name;
- private string _email;
- public User()
- {
- _age=25;
- _name="oec2003";
- _email = "[email protected]";
- }
- public User(Int32 age):this()
- {
- this._age = age;
- }
- public User(string name):this()
- {
- this._name = name;
- }
- public User(Int32 age, String name, String mail):this()
- {
- this._age = age;
- this._name = name;
- this._email = email;
- }
- }
CLR Via C#中值類型的實例構(gòu)造函數(shù)
值類型的實例構(gòu)造函數(shù)和引用類型的有很大不同,在值類型中不能含有無參的構(gòu)造函數(shù),如果顯式指定無參的構(gòu)造函數(shù)將會出現(xiàn)編譯錯誤。如下面代碼會出現(xiàn)編譯錯誤:
- struct User
- {
- public Int32 _age;
- public String _name;
- public User()
- {
- _age = 25;
- _name = "oec2003";
- }
- }
值類型不能包含無參的構(gòu)造函數(shù),也不能在值類型中給字段進(jìn)行初始化,下面的代碼也將不能通過編譯。
- public struct User
- {
- public Int32 _age=25;
- public String _name="oec2003";
- }
在值類型中也可以有構(gòu)造函數(shù),不過該構(gòu)造函數(shù)必須含有參數(shù),而且要初始化所有的字段。含有參數(shù)但沒有初始化所有字段的構(gòu)造函數(shù)也不能通過編譯。看下面代碼:由此可見如果值類型中顯示包含構(gòu)造函數(shù)必須要初始化所有的字段。
如果有多個構(gòu)造函數(shù),每個構(gòu)造函數(shù)也必須保證初始化所有的字段,否則不能通過編譯。如果值類型中不包含構(gòu)造函數(shù),實例化時所有字段將設(shè)置為0或null。
- public struct User
- {
- public Int32 _age;
- public String _name;
- //只初始化了_age
- public User(Int32 age)
- {
- _age = age;
- }
- public User(Int32 age,String name)
- {
- _age = age;
- _name = name;
- }
- }
CLR Via C#中類型構(gòu)造函數(shù)
類型構(gòu)造函數(shù)也被稱為靜態(tài)構(gòu)造函數(shù)。靜態(tài)構(gòu)造函數(shù)可以用于引用類型和值類型。和實例構(gòu)造函數(shù)不同的是靜態(tài)構(gòu)造函數(shù)在一個類型中永遠(yuǎn)只有一個,并且不能包含參數(shù)。靜態(tài)構(gòu)造函數(shù)中只能初始化靜態(tài)字段。
下面代碼分別展示在值類型(和實力構(gòu)造函數(shù)不同,值類型中允許顯示定義無參的靜態(tài)構(gòu)造函數(shù))和引用類型中的靜態(tài)構(gòu)造函數(shù)。
- //值類型
- public struct User
- {
- public static Int32 _age ;
- public static String _name;
- static User()
- {
- _age = 25;
- _name = "oec2003";
- }
- }
- //引用類型
- public class User
- {
- public static Int32 _age ;
- public static String _name;
- static User()
- {
- _age = 25;
- _name = "oec2003";
- }
- }
為了防止開發(fā)人員編寫的代碼調(diào)用靜態(tài)構(gòu)造函數(shù),C#編譯器會將靜態(tài)構(gòu)造函數(shù)定義為私有(private)的,并且不能顯示地給靜態(tài)構(gòu)造函數(shù)添加訪問修飾符,如果這么做了會出現(xiàn)編譯錯誤。
上面講到過在值類型中不能在定義是給實例字段賦值,否則會編譯錯誤,但可以在定義時給靜態(tài)字段賦值,看下面代碼:
- public struct User
- {
- public static Int32 _age = 25; //正確 可以初始化靜態(tài)字段
- public String _name = "oec2003"; //錯誤 不能初始實例字段
- }
CLR Via C#中靜態(tài)構(gòu)造函數(shù)不應(yīng)該去調(diào)用基類的靜態(tài)構(gòu)造函數(shù),因為靜態(tài)字段是不會被繼承到子類中,所以這樣做沒有意義。
【編輯推薦】
- 淺析基于SQL2005的CLR存儲過程
- 分析與對比CLR Via C#靜態(tài)構(gòu)造函數(shù)的性能
- 為你解疑:CLR是什么?
- linq to sql多表查詢淺析
- linq to sql多表基礎(chǔ)描述
網(wǎng)頁標(biāo)題:淺析CLRViaC#構(gòu)造函數(shù)
網(wǎng)址分享:http://m.fisionsoft.com.cn/article/dpojphp.html


咨詢
建站咨詢
