C# 幾個特殊運算符的理解和Nullable 的研究


 

可空值類型和?運算符

談到運算符,大家一定很熟悉,但是對所有的運算符都能掌握嗎? 看了下面代碼再回答。

1             Nullable<Int32> count = 3;
2             
3             int? i = 1;
4             
5             bool? flag = false;
6 
7             bool hasValue = flag ?? false;

 

相信在大多數情況下,對第三行和第7行的使用方法比較少。他們究竟代表啥含義,int?int 有什么區別, “??”運算符是什么意思?

這個問題就需要提到C#中可空值類型(Nullable),顧名思義,他就是一個可以為null的值類型,嗯,是為null的值類型,沒聽錯。不是值類型不能為空,為啥要引入一個可為空的值類型呢?這就需要涉及到實際開發中碰到的問題來看。例如,設計一個數據庫時,開獎一個列的數據類型定義為32位整數,並且可以映射到FCL的Int32。但是有些情況下,數據庫列為空,這樣從數據庫讀出來的數據在映射為FCL的數據類型時該怎么辦?CLR中不能講一個Int32表示成null

這樣引入可空值類型就是有必要的.上面代碼中第一行就是可空值類型的使用,他是一個泛型類

public struct Nullable<T> where T : struct { }

T 被限定為struct,即值類型,如果是引用類型就沒必要使用可空值類型,可以直接賦值為null。那么第三行的代碼是怎么回事呢? 這就是用"?"來表示的可空值類型,Nullable<Int32> 等同於 Int32? ,個人觀點來說Nullable<T>這種寫法更具有直觀性。

從上面看出可控制類型是個類,因此Nullable<Int32>Int32 是不能直接來用=賦值的(編譯器報錯),那么他們在使用過程中就進行類型轉換,例如

1             int x = 9;
2             int? a = x; //正確
3             int? z = (int?)x;//正確
4             //int y = a; //Error Cannot implicitly convert type 'int?' to 'int'
5             int y = (int)a;//正確

 

第二行代碼中賦值是進行了隱式類型轉換,編譯器沒有報錯,第三行進行顯式類型轉換也沒有問題。但是第四行就會報錯,需要強制類型轉換。那么有類型轉換,那么肯定會聯想到裝箱和拆箱,那么編譯器是怎么裝箱和拆箱的呢?

裝箱:當CLR對一個Nullable<T>實例進行裝箱時,首先檢查他是否為null,如果是,CRL不進行任何操作,直接返回null。如果實例不為null,CLR對可空值實例中的值進行裝箱 。

            Int32? n = null;
            object o = n;

拆箱:可以將一個已裝箱的值類型T拆箱成一個T或者一個Nullable<T>, 如果已裝箱的值類型引用為null,就拆箱成一個Nullable<T>,

1             object obj1 = null;
2             object obj2 = 1;
3             int? o1 = (int?)obj1;
4             int? o2 = (int?)obj2;
5             int i1 = (int)obj1;//NullException
6             int i2 = (int)obj2;

 

Nullable<T>的類型

下面我們來看一下Nullable<T>的類型,可以使用代碼查看,

1  
2             Nullable<Int32> count = 3;
3             Console.WriteLine(count.GetType());//"System.Int32"

為什么Nullable<Int32>的類型和Int32的類型相同呢?如果他們真的相同,為什么不能直接賦值,要進行強制轉換呢?這就是CLR對我們撒謊了。

??運算符

最后我們了解一下運算符“??”(null-coalescing operator 空接合運算符),他是一個類似於?:運算符的的運算符,a??b 表示如果a 不等於null,則返回a, 否則返回b。對於使用不使用,什么時候使用 仁者見仁智者見智,所以不多說,只給出一個例子。

1             Int32? temp = null;
2             Int32 temp1 = temp ?? 123; //Equals temp1 = temp.HasValue ? temp.Value:123;

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM