在C# 1.0出來時,實值型別是不可以為null,而參考型別是可以null的,畢竟參考型別變數實際儲存的只是記憶體heap空間的物件地址,而實值型別變數存的是物件真實數值。記憶體地址可以空值,代表沒有地址,然而數值則不可以是空值。若數值可以代表空值,以byte為例8個位元,可以儲存0到255共256種數值,要多儲存一個null有些奇怪。
資料庫中的NULL指的是那格欄位值是空白的
變數值是null,指的是變數並沒有對應的記憶體地值
兩者概念有點不一樣,前者指不管欄位是什麼資料型別都沒有填入資料形成空白,後者指記憶體地址空白。不過當C#程式遇到資料庫時,總是會遇到資料庫數值型別欄位可為空,但C#不可為空的情況。
然而在DateTime型別也是實值型別,在程式功能上總是會發生,在一個網路購物網站,資料庫的訂單資料表可能有以下欄位,訂單編號、是否繳費、繳費日期等,而發生下了訂單卻尚未繳費,所以繳費日期為空的狀態。
.NET Framework 2.0 開始提供了讓數值型別可以為null的泛型類別,實際的做法是用stack來包裝bool與int,若bool為false則回傳null,若bool為true則回傳int數值。實際用法如下:
Nullable<int> j = null;
Console.WriteLine(i);
若要其他可為null的實值型別,可以將<int>
替換成<double>
、<bool>
或<dateTime>
等原本不可以為null的實值型別。
我們一樣可以去https://referencesource.microsoft.com
看到原始碼是stack來包裝,形成一種可為null的實值型別
C#2.0有提供?號修飾詞,在int
後面加上?
修飾詞即會幫我們轉換成Nullable<int>
,使Nullable<int>
與int?
編譯後的IL兩者會一模一樣,原先C#不可為null的原始實值型別,皆可以在後面加上?替換成可為null實值型別
X|Y| |XandY |XorY |!X
---|---
true|null| |null|true|false
false|null| |false|null|true
null|null| |null|null|null