可空類型是System.Nullable結構體的實列。一個可空類型代表了相應實值型別的正確範圍附加null值。這麼說來,其實也不是很明子,命題嘛,一般不求易懂,但求準確。
那我就來說說這可空類型吧,上次說到了實值型別與參考型別,其中就說到了,實值型別是不可為空的,int i=null是錯的,實值型別為能為空白,但我們有時候需要讓實值型別也可以為空白,怎麼辦呢,那就在實值型別的值的範圍上擴充一個null值。
- 為什麼要有可空類型
-
我們在日常開發中,什麼地方需要讓實值型別也變成可空呢?如果你有試過把資料庫內的資料對象化的時候,面對資料庫中的欄位定義如:
要轉化成對象
public class XXXX{ public int id { get; set; } //……}
這時候就出現問題了,在資料庫中是允許為空白的,但是在類設計的時候,int類型就是不允許為空白的,你不給它賦值,它也是有預設值0的。怎麼辦?這與資料庫的設計是有衝突的,於是,就必須使用咱們的可空類型,我個人理解這也就是為什麼要有可空類型的原因。
怎麼表示可空類型
使用可空類型,上面的類就可以寫成
public class XXXX{ public int? id { get; set; } //……}
沒看錯,就是在int後面加上?號,這就是可空類型的表示,當然還有其它的表示方式
Nullable<int> d = null;
這兩種表示方式其實是等效的,就根據喜好和使用情境靈活使用就行。
怎麼判斷是null還是其它值
對於可空類型,我們可以很簡單地使用null與可空類型進行比較,就可能判斷變數的值是否為null。如:
Nullable<int> d = null;bool isNull = d == null ? true : false;
當然,我還有其它的辦法與方法來做這同樣效果的事,如:
Nullable<int> d = null;bool isNull = !d.HasValue;
注意,如果HasValue是為false時,使用 var result=d.Value時,會拋出異常System.InvalidOperationException
根據情況,根據需要,靈活使用以上兩種判斷方法。
可空類型怎麼給實值型別賦值
可空類型不可以直接轉化成實值型別,也不可以直接對實值型別賦值,如:
Nullable<int> d = null;int result = d;//錯 int result = (int)d;//錯
那怎麼做呢,最簡單的辦法就是
Nullable<int> d = null;int result = d.GetValueOrDefault();
這時result的值為0;
或者也可以判斷是否為空白,對它進行賦值
Nullable<int> d = null;int result;if (!d.HasValue){ result = d.Value;}
如果可空類型是經過運算給實值型別賦值。那就還有一種辦法
Nullable<int> d = null;int result = d ?? +1;
即使用??進行轉意。這是的result的值為1;
反射中的可空類型
我們經常會在反射中使用的可空類型,那怎麼來使用可空類型呢?
public class NullableTest{ public int? ID { get; set; }}
var propertyInfo= typeof(NullableTest).GetProperty("ID");
查詢變數的值時,我們會發現
propertyInfo.PropertyType.Name |
Nullable`1 |
propertyInfo.PropertyType.IsGenericType |
true |
propertyInfo.PropertyType.IsGenericTypeDefinition |
false |
propertyInfo.PropertyType.GetGenericTypeDefinition().Name |
Nullable`1 |
我們根本無法使用一般泛型得到泛型基底類型的方法GetGenericTypeDefinition()得到可空類型的基底類型,此時,我們就需要使用GetGenericArguments()去得到泛型的基礎類型。
var propertyInfo = typeof(NullableTest).GetProperty("ID");if (propertyInfo.PropertyType.IsGenericType && propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)){ Type[] typeArray = propertyInfo.PropertyType.GetGenericArguments(); Type baseType = typeArray[0];}
做到這裡,我們就可以使用反射來完成任何我們想要的操作了。