摘要:.NET Framework 2.0 筆記:Nullable Types
顧名思義,Nullable 型別就是允許存入 null 值的型別,這當然不是用在參考型別,因為參考型別的變數值本來就可以是 null;它的用途是讓基礎型別(簡單型別)的變數可以有 null 值。例如,資料庫中的整數或布林欄位都可以設定成允許 null,如果某個整數欄位值為 null,那麼取出來存到一般的整數變數時就會有問題。
宣告與初始化
宣告 nullable type 變數的語法有兩種,參考以下範例:
Nullable<int> x = new Nullable<int>(10); int? x = 10;
如果 nullable type 變數有值,除了可以跟平常一樣直接讀取變數值,也可以利用它的 Value 屬性來取值,例如:
int? x = 10; Console.WriteLine(x.Value);
但是要注意,如果 nullable type 變數值為 null,上面的程式碼執行時就會出現 exception,因為這樣就變成了要存取一個「沒有東西」的 Value 屬性。
判斷式
判斷某個 nullable type 變數是否為 null 有兩種方法,一個是用 == 或 != 運算子,另一個是用 nullable 型別的 HasValue 屬性,例如:
int? x = null; if (x != null) .... if (x.HasValue) ....
注意如果是 nullable 布林型別,當其變數值為 null 時,用在真偽的判斷式中都會傳回 false:
bool? x = null; if (x) // always false Console.WriteLine("false");
另外還有一種簡潔的判斷語法,是用 ?? 運算子,例如:
int? x = null; int? y = x ?? 5;
第二行的作用等同於
int? y = (x != null) ? x : 5;
與非 nullable type 混用
Nullable type 變數不能直接指定給一般的變數,例如:
int? x = 10; int y = x;
第二行會無法通過編譯。但是如果用明確轉型:
int y = (int) x;
就可以編譯過。但問題是,如果 x 是 null,儘管可以編譯過,執行時還是會發生 exception,因為 y 是一般的型別,它無法接受 null 值。
另外,任何與 null 值運算的結果,都會是 null,例如:
int? m = null; int? n = 10; int? o = m + n; int? p = m * n; Console.WriteLine("Nullable 變數運算: m + n = " + o); Console.WriteLine("Nullable 變數運算: m * n = " + p);
執行結果為:
Nullable 變數運算: m + n = Nullable 變數運算: m * n =
Nullable 與非 nullable 型別可以相互運算:
int? m = 10; int n = 5; int? p = m * n; Console.WriteLine("m * n = " p);
執行結果為:
m * n = 50
但是注意運算的結果也是 nullable type,因此本例的變數 p 必須是 nullable type。
Nullable type 的真正型別
到底 nullable type 編譯之後的實際型別是什麼呢?可以用以下簡單的程式碼測試一下:
{
int x = 10;
int? y = 5;
Console.WriteLine("type x: {0}", x.GetType().Name);
Console.WriteLine("type y: {0}", y.GetType().Name);
Console.WriteLine("type z: {0}", ( x * y ).GetType().Name);
return 0;
}
輸出:
type x: INT32
type y: INT32
type z: INT32