天天看點

詳細了解 int? 類型

int?是什麼;了解Nullable結構體;Nullable類型中的GetValueOrDefault方法與運算符重載

一、int?是什麼

二、了解Nullable結構體

三、Nullable類型的取值與轉換

         1.GetValueOrDefault

         2.運算符重載

說到int?,或者double?,平時隻是在接收資料庫傳來的可空值類型資料時用用。

但int既然是值類型,不能為空,為什麼int?就可空了呢,引用類型才是可空的,難道int?是引用類型?

測試一下吧:

1. 寫一句int?=3,看看反編譯結果

詳細了解 int? 類型

2. 編譯結果裡有關鍵字new,我們也new一個試試

結果發現int?有兩個重載

重載1:

詳細了解 int? 類型

重載2:

詳細了解 int? 類型

重載2包含一個int型參數,并解釋說會執行個體化一個Nullable<T>結構體

3. 手動執行個體化Nullable<T>

發現Nullable<int> test=new Nullable<int>(1);這樣的寫法是可行的

下面是三種不同的寫法及其反編譯代碼:

詳細了解 int? 類型
詳細了解 int? 類型

可見,這三種寫法是等價的。

Nullable結構體長這樣:

詳細了解 int? 類型

但既然int? 是Nullable結構體的特例,為什麼就可以指派為null呢?

模仿上面的Nullable自己封裝一個Nullable1并使用,看看效果

詳細了解 int? 類型

結果是Nullable可以指派為null,自己寫的Nullable1卻不可以,而且Nullable與Nullable1兩個類型的顔色還有點深淺的差別,很奇怪

把錯誤的代碼屏蔽,反編譯看看IL代碼,Nullable<int> e=null;對應的是這樣的

詳細了解 int? 類型

把Nullable<int> e=null; 改為Nullable<int> e=1;再看看結果:

詳細了解 int? 類型

再找一個引用類型并指派為null,比如string s=null; 的IL代碼為:

詳細了解 int? 類型

可見對于Nullable<int> e=null;來說,null對應的IL碼為initobj;而對于string s=null來說null對應的IL碼則是idnull,這兩個地方的null是不同的

但我們不是也可以用e==null這樣的寫法嗎,難道這兒的null也是特殊的用法

繼續測試代碼,結果為true

詳細了解 int? 類型

反編譯

詳細了解 int? 類型

原來這兒的d==null相當于!d.HasValue

HasValue屬于Nullable結構體的成員

對這一系列現象不清楚了,可能Nullable<int> e=null中的null用來特指Nullable結構體中Value為空時的狀态吧,懇請大神指教

三、Nullable類型的取值與轉換       

最後再試試Nullable結構體中的兩個GetValueOrDefault方法以及兩個運算符重載

1. GetValueOrDefault

對于為空的變量,GetValueOrDefault()會傳回0;GetValueOrDefault(T defaultValue)則會傳回指定的defaultValue的值。

另外,c# 7.0的新文法“??”與這個方法有相同的作用

詳細了解 int? 類型

2.運算符重載

顯式運算符重載:

詳細了解 int? 類型

隐式運算符重載:

詳細了解 int? 類型

顯式重載的參數為可空值類型,傳回結果為Nullable結構體的Value屬性;

隐式重載的參數為普通值類型,傳回結果為一個Nullable結構體,同時其Value屬性已經被指派

比如,有兩個參數a、b

int a;

int? b=0;

将b指派給a,會使用顯式重載,要寫成a = (int)b;

而将a指派給b,則會使用隐式重載,可直接b = a;