問題一:Nullable<T>可賦值為null
先看兩行C#程式碼
int? i1 = null; int? i2 = new int?();
int? 即Nullable<int>,就像int之於Int32;
Nullable<T>是非常特殊結構型別,它可賦值為null(所以此前我還以為是引用型別),其本質是等同於new;
通過除錯可發現上述兩個值均為null,但是事實上我們卻可以呼叫他們的一些屬性方法比如“HasValue”,由此可見“=null“只是障眼法罷了;
此時如果呼叫他們的”Value“屬性將引發”InvalidOperationException“異常,注意不是空引用異常,異常資訊為”其他資訊: 可為空的物件必須具有一個值。”;
建議對於此型別的取值使用“GetValueOrDefault”方法來獲取,而不是判斷HasValue後去Value值;
其次建議不進行” == null “的邏輯判斷,應使用HasValue屬性。
問題二:Nullable<T> 可賦值為 T型別
仍然看兩行C#程式碼
int? iNull = 2; int i = (int)iNull;
非常常見的程式碼,但是每行程式碼都包含了型別,“int?”與int之間的隱式轉換與顯示轉換,而支援可空型別轉換的就是Nullable<T>提供了兩個方法:
public static explicit operator T(Nullable<T> value); public static implicit operator Nullable<T>(T value);
operator是運算子過載,因而這倆貨也可以看成是對“=”的運算子過載,explicit支援了顯示轉換,implicit支援了隱式轉換,使用如下:
class UserInfo { public int ID { get; set; } public string Name { get; set; } public static explicit operator UserInfo(int id) { Console.WriteLine("獲取使用者ID為【{0}】的User物件", id); return new UserInfo { ID = id }; } public static implicit operator UserInfo(string name) { Console.WriteLine("獲取使用者名稱為【{0}】的User物件", name); return new UserInfo { Name = name }; } }
呼叫:
UserInfo user1 = (UserInfo)2; UserInfo user2 = "bajie";