可空類型

来源:http://www.cnblogs.com/Helius/archive/2016/08/07/5747399.html
-Advertisement-
Play Games

可空類型、匿名方法和迭代器這三個優美的特性是在C#2.0裡面提出來的。 1、可空類型 當我們在使用資料庫的時候,會發現這樣的一個矛盾點:資料庫的欄位設置是允許為null的,比如日期的欄位,當你想把資料庫表映射為C#中的對象時會發現,DateTime類型在C#語言中是不能為null的! 1.1 簡介 ...


可空類型、匿名方法和迭代器這三個優美的特性是在C#2.0裡面提出來的。

1、可空類型

當我們在使用資料庫的時候,會發現這樣的一個矛盾點:資料庫的欄位設置是允許為null的,比如日期的欄位,當你想把資料庫表映射為C#中的對象時會發現,DateTime類型在C#語言中是不能為null的!

   1.1 簡介

         可空類型也是值類型,但它是包含null值的值類型:int? nullable=null;

         int?就是可空的int類型。很明顯,這又是一個語法糖,肯定不會存在int?這樣的類型。對於編譯器而言,int?會被編譯成Nullable<int>類型,即可空類型。

         C#2.0中提供的可空類型是Nullable<T>和Nullable(這個T就是一個泛型參數)。在C#中,定義是這樣的public struct Nullable<T> where T:struct ,很明顯,泛型只能是值類型。下麵的代碼演示了可空類型的使用方法:

          

 1 static void Main(string[] args)
 2 
 3 {
 4 Nullable<int> value = 1;//int? value=1也可以
 5 Console.WriteLine("可空類型有值的輸出情況:");
 6 Display(value);
 7 Console.WriteLine();
 8 
 9 value = new Nullable<int>();
10 Console.WriteLine("可空類型沒有值的輸出情況:");
11 Display(value);
12 Console.ReadKey();
13 
14 }
15 
16 private static void Display(int? value)
17 {
18 Console.WriteLine("可空類型是否有值:{0}",value.HasValue);
19 if (value.HasValue)
20 {
21 Console.WriteLine("值為:{0}",value.Value);
22 }
23 //如果可空類型有值,則返回Value屬性的值,否則就返回預設值
24 Console.WriteLine("GetValueorDefault():{0}",value.GetValueOrDefault());
25 //如果可空類型有值,則返回Value屬性的值,否則就返回2
26 Console.WriteLine("GetValueorDefault():{0}", value.GetValueOrDefault(2));
27 //如果HasValue屬性為true,則Value屬性返回對象的哈希代碼,否則為0
28 Console.WriteLine("GetHashCode()方法的使用:{0}",value.GetHashCode());
29 }

    1.2 空合併操作符

          即為??操作符,它會對左右兩個操作數進行判斷,如果左邊的數不為null,就返回左邊的數;如果左邊的數為null,就返回右邊的數。這個操作符可用於可空類型,也可以用於引用類型,但是不能用於值類型。例如:

1 string stringnotnull="123"
2 string stringisnull=null;
3 string result=stringnotnull ?? "456";
4 string result=stringisnull ?? "12";

以上的代碼運行結果為:result=“123”;result2=“12”。

    1.3 可空類型的裝箱與拆箱操作

          既然值類型存在著裝箱和拆箱的過程,而可空類型屬於值類型,那麼它自然也就存在裝箱和拆箱操作,下麵我們就來看看可空類型的裝箱和拆箱的過程。

          當把一個可空類型賦給引用類型變數時,CLR會對可空類型(Nullable<T>)對象進行裝箱處理。CLR首先檢測可空類型是否為null。如果有null,CLR將不會進行實際的裝箱操作(因為null可以直接賦值給一個引用類型變數);如果不為null,CLR則從可空類型對象中獲取值,並對該值進行裝箱(即值類型的裝箱過程)。

          當把一個已裝箱的值類型賦值給可空類型變數時,CLR會對已裝箱的值類型進行拆箱處理。如果已裝箱值類型的引用為null,則CLR會把可空類型也設為null。

          

 1 static void Main(string[] args)
 2         {
 3             Console.WriteLine("可空類型的裝箱和拆箱的使用如下:");
 4             BoxAndUnbox();
 5             Console.ReadKey();
 6         }
 7 
 8         private static void BoxAndUnbox()
 9         {
10             Nullable<int> nullable = 5;
11             int? nullablewithoutvalue = null;
12             Console.WriteLine("讀取不為null的可空類型的類型為{0}",nullable.GetType());
13             //出現NullReferenceException的異常
14             //Console.WriteLine("讀取為null的可空類型的類型為{0}", nullablewithoutvalue.GetType());
15             object obj = nullable;
16             Console.WriteLine("獲得裝箱後obj的類型:{0}",obj.GetType());
17 
18             int value = (int) obj;
19             nullable = (int?) obj;
20 
21             //對一個沒有值的可空類型的對象進行裝箱操作
22             obj = nullablewithoutvalue;
23             Console.WriteLine("對null的可空類型裝箱後obj是否為null:{0}",obj==null);
24 
25             //拆箱一定要為可空類型
26             nullable = (int?) obj;
27         }

 

運行的結果如下:

由以上的結果可以得知:

(1)通過GetType方法來獲得賦值的可空類型時,返回的將是賦值的類型,在前面的的代碼中即是System.Int32,而不是System.Nullable<System.Int32>類型。

(2)對已賦值的可空類型裝箱後,如果使用GetType函數去獲得裝箱後的引用類型,輸出的將仍然是賦值的類型,在前面的代碼中即為System.Int32。

(3)如果把一個沒有值的可空類型裝箱之後再拆箱,不能拆箱為非可空類型的值類型,否則會拋出NullReferenceException異常。因為沒有值的可空類型裝箱後obj等於null,即引用一個空地址,如果拆箱為非可空類型的值類型,相當於把null賦值給一個int型的變數,而int類型屬性值類型,不能被賦值為null,因此會出現異常。

(4)還有一點必須要註意:沒有值的可空類型在調用GetType函數之前,編譯器會對可空類型進行裝箱操作,使其變為null,即空引用。所以之後再調用GetType函數時,就會拋出空引用異常了。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 存儲過程:就像函數一樣的會保存在資料庫中--》可編程性 --》 存儲過程創建存儲過程:create proc JiaFa--需要的參數@a int,@b intas --存儲過程的內容 declare @c int; set @c = @a + @b; return @c;go public int ...
  • .NET Core中間件的註冊和管道的構建(2) 用UseMiddleware擴展方法註冊中間件類 0x00 為什麼要引入擴展方法 有的中間件功能比較簡單,有的則比較複雜,並且依賴其它組件。除了直接用ApplicationBuilder的Use()方法註冊中間件外,還可以使用ApplicationB ...
  • It has being ages to get back to cnblogs, Career path had been changed back to .Net development in 4 years ago....Things i just leart from my current ...
  • 什麼是Linq表達式?什麼是Lambda表達式? 如圖: 由此可見Linq表達式和Lamdba表達式並沒有什麼可比性。 那與Lamdba表達式相關的整條語句稱作什麼呢?在微軟並沒有給出官方的命名,在《深入理解C#》中稱為點標記。 ...
  • 背水一戰 Windows 10 之 控制項(文本類): TextBlock ...
  • 目錄索引 【無私分享:ASP.NET CORE 項目實戰】目錄索引 簡介 在程式設計中,我們很多情況下,會用到對文件的操作,在 上一個系列 中,我們有很多文件基本操作的示例,在Core中有一些改變,主要是我們常用的Server.MapPath()不存在了,不知道後續的版本會不會有,在這裡,我們只能自 ...
  • 前提: 自定義搜索且有分頁功能,比如搜索產品名的功能. 現象:當搜索充氣娃娃的時候返回100條記錄,翻到第五頁. 這時候搜索按摩棒,數據有200條,結果應該是第一頁的記錄,但是實際顯示的還是第五頁的結果. 也就是重新搜索後,pagenumber沒有變. 按網上大部分說的:重新設置option就行了 ...
  • 3.2自定義路由事件 為了方便程式中對象之間的通信,通常需要我們自己定義一些路由事件。那麼如何去創建自定義路由事件呢?下麵通過一個例子來說明自定義路由事件的創建。 創建自定義路由事件大體來說分為三個步驟: 首先,定義路由事件與依賴屬性的定義手法極為相似——申明一個由public static rea ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...