2015-12-03 31 views
3

我一直在尋找的.NET Nullable<T>類下面的代碼:http://referencesource.microsoft.com/#mscorlib/system/nullable.cs,ffebe438fd9cbf0e可空初始化爲空 - 理解源代碼

,我想知道,這將是它下面的使用行爲:

int? x = null;

顯然,x.hasValue()回報false,但是我看到,在構造函數中,hasValue屬性始終設置爲true

那麼我錯過了什麼?

+3

由於沒有值,因此將調用默認構造函數,它將'hasValue'初始化爲默認值'false'。 – Lee

回答

6

「構造」,是的,這是明確的書面Nullable<T>的構造,但是所有的結構有一個額外的構造函數,你不是一個無參數的默認構造函數允許執行。這將永遠存在。

所以可以認爲從你的問題中的代碼,類似這樣的:

int? x = new Nullable<int>(); 

事實上,如果我們編譯代碼和我的代碼,並期待在產生IL:

您的代碼:

IL_0001: ldloca.s 00 // a 
IL_0003: initobj  System.Nullable<System.Int32> 

我的代碼:

IL_0001: ldloca.s 00 // a 
IL_0003: initobj  System.Nullable<System.Int32> 

所以他們是完全一樣的。

爲一個結構的默認構造函數初始化所有字段逐字節零,這相當於爲假布爾字段,0號的字段,用於null引用類型字段等

1

從文檔上MSDN

的Structs不能包含明確的參數構造函數。結構成員會自動初始化爲默認值。

這意味着總是有一個'默認無參數構造函數'。你沒有看到它,但它總是在那裏。如果您傳遞的值爲T(不可爲空),則構造函數可以假定它具有值。

嘗試比如這一個:

Nullable<int> c = new Nullable<int>(); 
Console.WriteLine(c.HasValue); // false 

c = new Nullable<int>(1); 
Console.WriteLine(c.HasValue); // true 
1

空類型是在治療C#的特殊方式,不像常規的struct s。

無法將null分配給常規的struct變量,但可以將其分配給Nullable<T>變量。爲什麼?它在C#語言規範中描述,6.1.5節

6.1。5空字面轉換

存在從null文字到任何可空類型的隱式轉換。此轉換會生成給定可空類型的空值(第4.1.10節)。

編譯器將此轉換實現爲默認無參數構造函數Nullable<T>的調用。每個struct都有一個隱含的無參數構造函數,它將所有字段初始化爲默認值。默認值boolfalse