基元類型爲何須要爲null?考慮兩個場景:數據庫
1)數據庫中一個int字段能夠被設置爲null。在C#中,值被取出來後,爲了將它賦值給int類型,不得不首先判斷一下它是否爲null。若是將null直接賦值給int類型,會引起異常。服務器
2)在一個分佈式系統中,服務器須要接收並解析來自於客戶端的數據。一個int型數據可能在傳輸過程當中丟失或被篡改了,轉型失敗後應該保存爲null值,而不是提供一個初始值。分佈式
相似的場景還有不少,因此從.NET 2.0開始,FCL中提供了一個額外的類型:能夠爲空的類型Nullable<T>。它是一個結構體,聲明以下:blog
[SerializableAttribute] public struct Nullable<T> where T : struct
由於是結構體,因此只有值引用類型才能夠做爲「能夠爲空的類型」(引用類型自己就能夠爲null)。一個能夠爲空的int類型表示爲:class
Nullable<int> i = null;
它也能夠表示爲:基礎
int? i = null;
語法T?是Nullable<T>的簡寫,二者能夠相互轉換。能夠爲 null 的類型表示其基礎值類型正常範圍內的值再加上一個null值。例如,Nullable<Int32>,其值的範圍爲-2 147 483 648 ~ 2 147 483 647,再加上一個null值。語法
如今來看看可空類型和基元類型的互相轉換。基元類型提供了其對應的可空類型的隱式轉換,以下所示:引用
int? i = null; int j = 0; i = j;
反過來,可空類型不可隱式轉換爲對應的基元類型,正確的轉換形式以下:數據
int? i = 123; int j ; if (i.HasValue) { j = i.Value; } else { j = 0; }
可是,這段代碼看上去是否是有點煩瑣?因此,在闡述可空類型的時候,不得不提到??運算符。??最大的用處就是將可空類型的值賦值給對應的基元類型進行簡化,上文代碼的一個簡化形式就是:客戶端
int? i = 123; int j = i ?? 0;
int j = i ?? 0;表示的意思是,若是i的HasValue爲true,則將i的value賦值給j;不然,就給j賦值爲0。