小結:
可空實值型別[Nullable value type]
1. 一個實值型別的變數永遠不可能為null,它總是包含實值型別的值本身。但某些情況下,這會帶來問題。例如,設計一個資料庫時,可以將一個列的資料類型定義成一個32位整數,並映射到FCL的Int32資料類型。但是,資料庫中的一個列是允許值為空白的,使用.Net Framework來處理資料庫資料可能變得相當困難,因為CLR中沒有辦法將一個Int32值表示成null。
為瞭解決這個問題,Microsoft在CLR中添加了可空實值型別(nullable value type)【System.Nullable< T >】的概念。
CLR中的定義:public struct Nullable<T> where T : struct{...}
2. C#對可空實值型別的支援
C#中採用問號標記法來聲明並初始化可空實值型別變數:
Int32? x = 5;
Int32? y = null;
3. C#的空合併作業符[??]
擷取兩個運算元,假如左邊的運算元不為null,就返回這個運算元的值;如果左邊的運算元為null,就返回右邊的運算元的值。利用空合併作業符,可以方便地設定變數的預設值。
空合併作業符的一個好處在於:它既能用於參考型別,也能用於可空實值型別。如:
Int32? b = null;
Int32 x = b ?? 123; //等價於: Int32 x = (b.HasValue) ? b.Value : 123;
String temp = GetFilename();
String filename = GetFilename() ?? "Untitled";//等價於: filename = (temp != null) ? temp : "Untitled";
4. 對可空實值型別進行裝箱
當CLR對一個Nullable<T>執行個體進行裝箱時,它會檢查它是否為null。如果是,CLR不會對它進行任何裝箱操作,直接返回null值。如果可空執行個體不為null,CLR就從可空執行個體中取出值,並對其進行裝箱。也就是說,一個值為5的Nullable<Int32>會裝箱成值為5的Int32類型。
Int32? x = 5;
Int32? y = null;
Object o = y;//不會進行裝箱操作,返回null值
Console.WriteLine("o is null = {0}", o == null);//"true"
Object o = x;//o引用一個已裝箱的Int32
Console.WriteLine("o's type is {0}", o.GetType());//"System.Int32"
5. 對可空實值型別進行拆箱
Object o = 5;//o引用一個已裝箱的Int32
Int32 a = (Int32)o;//拆箱成一個Int32
Int32? b = (Int32?)o;//拆箱成一個Nullable<Int32>
6. 通過可空實值型別來調用GetType
在一個Nullable<T>對象上調用GetType時,CLR實際返回的是T類型,而不是Nullable<T>,如:
Int32? x = 5;
Console.WriteLine(x.GetType());//顯示"System.Int32",而非Nullable<Int32>