最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#基礎(chǔ)知識 全面解析可空類型

 更新時間:2012年11月23日 14:57:24   作者:  
C# 2.0 中還引入了可空類型,可空類型也是值類型,只是可空類型是包括null的值類型的,下面就介紹下C#2.0中對可空類型的支持具體有哪些內(nèi)容

引言:

  C# 2.0 中還引入了可空類型,可空類型也是值類型,只是可空類型是包括null的值類型的,下面就介紹下C#2.0中對可空類型的支持具體有哪些內(nèi)容(最近一直都在思考如何來分享這篇文章的,因為剛開始覺得可空類型使用過程中比較簡單,覺得沒有講的必要,但是考慮到這個系列的完整性,決定還是嘮叨下吧,希望對一些不熟悉的人有幫助)。

一、為什么會有可空類型

   如果朋友們看了我之前的分享,對于這一部分都不會陌生,因為我一般介紹C#特性經(jīng)常會以這樣的方式開頭的, 因為每個特性都是有它出現(xiàn)的原因的(有一句佛語這是這么講的:萬事皆有因,有因必有果),首先來說說這個因的(果當(dāng)然是新增加了可空類型這個新特性了。),當(dāng)我們在設(shè)計數(shù)據(jù)庫的時候,我們可以設(shè)置數(shù)據(jù)庫字段允許為null值,如果數(shù)據(jù)庫字段是日期等這樣在C#語言是值類型時,當(dāng)我們把數(shù)據(jù)庫表映射一個對象時,此時Datetime類型在C# 語言中是不能為null的,如果這樣就會與數(shù)據(jù)庫的設(shè)計有所沖突,這樣開發(fā)人員就會有這樣的需求了——值類型能不能也為可空類型的?同時微軟也看出了用戶有這樣的需求,所以微軟在C# 2.0中就新增加了一種類型——可空類型,即包含null值的值類型,這個也就是我理解的因了,介紹完因之后,當(dāng)然就是好好嘮叨下可空類型是個什么東西的了?

二、可空類型的介紹

   可空類型也是值類型,只是它是包含null的一個值類型。我們可以像下面這樣表示可空類型(相信大家都不陌生):

復(fù)制代碼 代碼如下:

int? nullable = null;

  上面代碼 int? 就是可空的int類型(有人可能會這樣的疑問的, 如果在C#1中我硬要讓一個值類型為一個可空類型怎么辦到呢?當(dāng)然這個在C#1之前也是有可以辦到的,只是會相當(dāng)麻煩,對于這個如果有興趣的朋友可以去刨下根),然而其實 "?"這個修飾符只是C#提供的一個語法糖(所謂語法糖,就是C#提供的一種方便的形式,其實肯定沒有int? 這個類型,這個int?編譯器認為的就是Nullable<int>類型,即可空類型),其實真真C# 2.0提供的可空類型是——Nullable<T>(這個T就是上專題介紹的泛型參數(shù),其中T只能為值類型,因為從可空類型的定義為:public struct Nullable<T> where T : struct)和Nullable。下面給出一段代碼來介紹可空類型的使用:

復(fù)制代碼 代碼如下:

namespace 可空類型Demo
{
class Program
{
static void Main(string[] args)
{
// 下面代碼也可以這樣子定義int? value=1;
Nullable<int> value = 1;

Console.WriteLine("可空類型有值的輸出情況:");
Display(value);
Console.WriteLine();
Console.WriteLine();

value = new Nullable<int>();
Console.WriteLine("可空類型沒有值的輸出情況:");
Display(value);
Console.Read();
}

// 輸出方法,演示可空類型中的方法和屬性的使用
private static void Display(int? nullable)
{
// HasValue 屬性代表指示可空對象是否有值
// 在使用Value屬性時必須先判斷可空類型是否有值,
// 如果可空類型對象的HasValue返回false時,將會引發(fā)InvalidOperationException異常
Console.WriteLine("可空類型是否有值:{0}", nullable.HasValue);
if (nullable.HasValue)
{
Console.WriteLine("值為: {0}", nullable.Value);
}

// GetValueOrDefault(代表如果可空對象有值,就用它的值返回,如果可空對象不包含值時,使用默認值0返回)相當(dāng)與下面的語句
// if (!nullable.HasValue)
// {
// result = d.Value;
// }

Console.WriteLine("GetValueorDefault():{0}", nullable.GetValueOrDefault());

// GetValueOrDefault(T)方法代表如果 HasValue 屬性為 true,則為 Value 屬性的值;否則為 defaultValue 參數(shù)值,即2。
Console.WriteLine("GetValueorDefalut重載方法使用:{0}", nullable.GetValueOrDefault(2));

// GetHashCode()代表如果 HasValue 屬性為 true,則為 Value 屬性返回的對象的哈希代碼;如果 HasValue 屬性為 false,則為零
Console.WriteLine("GetHashCode()方法的使用:{0}", nullable.GetHashCode());
}
}
}

輸出結(jié)果:

上面的演示代碼中都注釋,這里就不再解釋了,為了讓大家明白進一步理解可空類型是值類型,下面貼出中間語言代碼截圖:

三、空合并操作符(?? 操作符)

  ??操作符也就是"空合并操作符",它代表的意思是兩個操作數(shù),如果左邊的數(shù)不為null時,就返回左邊的數(shù),如果左邊的數(shù)為null,就返回右邊的數(shù),這個操作符可以用于可空類型,也可以用于引用類型,但是不能用于值類型(之所以不能應(yīng)用值類型(這里除了可空類型),因為??運算符要對左邊的數(shù)與null進行比較,然而值類型,不能與null類型比較,所以就不支持??運算符),下面用一個例子來掩飾下??運算符的使用(??這個運算符可以方便我們設(shè)置默認值,可以避免在代碼中寫if, else語句,簡單代碼數(shù)量,從而有利于閱讀。)

復(fù)制代碼 代碼如下:

static void Main(string[] args)
{
Console.WriteLine("??運算符的使用如下:");
NullcoalescingOperator();
Console.Read();
}

private static void NullcoalescingOperator()
{
int? nullable = null;
int? nullhasvalue = 1;

// ??和三目運算符的功能差不多的
// 所以下面代碼等價于:
// x=nullable.HasValue?b.Value:12;
int x = nullable ?? 12;

// 此時nullhasvalue不能null,所以y的值為nullhasvalue.Value,即輸出1
int y = nullhasvalue ?? 123;
Console.WriteLine("可空類型沒有值的情況:{0}",x);
Console.WriteLine("可空類型有值的情況:{0}", y);

// 同時??運算符也可以用于引用類型, 下面是引用類型的例子
Console.WriteLine();
string stringnotnull = "123";
string stringisnull = null;

// 下面的代碼等價于:
// (stringnotnull ==null)? "456" :stringnotnull
// 同時下面代碼也等價于:
// if(stringnotnull==null)
// {
// return "456";
// }
// else
// {
// return stringnotnull;
// }
// 從上面的等價代碼可以看出,有了??運算符之后可以省略大量的if—else語句,這樣代碼少了, 自然可讀性就高了
string result = stringnotnull ?? "456";
string result2 = stringisnull ?? "12";
Console.WriteLine("引用類型不為null的情況:{0}", result);
Console.WriteLine("引用類型為null的情況:{0}", result2);
}

下面是運行結(jié)果截圖:

四、可空類型的裝箱和拆箱

   值類型存在裝箱和拆箱的過程,可空類型也屬于值類型,從而也有裝箱和拆箱的過程的, 這里先介紹下裝箱和拆箱的概念的, 裝箱指的的從值類型到引用類型的過程,拆箱當(dāng)然也就是裝箱的反過程,即從引用類型到值類型的過程(這里進一步解釋下我理解的裝箱和拆箱,首先.Net中值類型是分配在堆棧上的,然而引用類型分配在托管堆上,裝箱過程就是把值類型的值從推棧上拷貝到托管堆上,然后推棧上存儲的是對托管堆上拷貝值的引用,然而拆箱就是把托管堆上的值拷貝到堆棧上.簡單一句話概況,裝箱和拆箱就是一個值的拷貝的一個過程,就想搬家一樣,把東西從一個地方搬到另一個地方,對于深入的理解,大家可以參考下園中的博文.), 括號中是我理解的裝箱和拆箱的過程,下面就具體介紹下可空類型的裝箱和拆箱的:

  當(dāng)把一個可空類型賦給一個引用類型變量時,此時CLR 會對可空類型(Nullable<T>)對象進行裝箱處理,首先CLR會檢測可空類型是否為null,如果為null,CLR則不進行實際的裝箱操作(因為null可以直接賦給一個引用類型變量),如果不為null,CLR會從可空類型對象中獲取值,并對該值進行裝箱(這個過程就是值類型的裝箱過程了。),當(dāng)把一個已裝箱的值類型賦給一個可空類型變量時,此時CLR會對已裝箱的值類型進行拆箱處理,如果已裝箱值類型的引用為null,此時CLR會把可空類型設(shè)為null(如果覺得啰嗦,大家可以直接看下面的代碼,代碼中也會有詳細的注釋)。下面用一個示例來演示下可空類型的裝箱和拆箱的使用,這樣可以幫助大家更好的理解前面介紹的概念:

復(fù)制代碼 代碼如下:

static void Main(string[] args)
{
//Console.WriteLine("??運算符的使用如下:");
//NullcoalescingOperator();
Console.WriteLine("可空類型的裝箱和拆箱的使用如下:");
BoxedandUnboxed();
Console.Read();
}

// 可空類型裝箱和拆箱的演示
private static void BoxedandUnboxed()
{
// 定義一個可空類型對象nullable
Nullable<int> nullable = 5;
int? nullablewithoutvalue = null;

// 獲得可空對象的類型,此時返回的是System.Int32,而不是System.Nullable<System.Int32>,這點大家要特別注意下的
Console.WriteLine("獲取不為null的可空類型的類型為:{0}",nullable.GetType());

// 對于一個為null的類型調(diào)用方法時出現(xiàn)異常,所以一般對于引用類型的調(diào)用方法前,最好養(yǎng)成習(xí)慣先檢測下它是否為null
//Console.WriteLine("獲取為null的可空類型的類型為:{0}", nullablewithoutvalue.GetType());

// 將可空類型對象賦給引用類型obj,此時會發(fā)生裝箱操作,大家可以通過IL中的boxed 來證明
object obj = nullable;

// 獲得裝箱后引用類型的類型,此時輸出的仍然是System.Int32,而不是System.Nullable<System.Int32>
Console.WriteLine("獲得裝箱后obj 的類型:{0}", obj.GetType());

// 拆箱成非可空變量
int value = (int)obj;
Console.WriteLine("拆箱成非可空變量的情況為:{0}", value);

// 拆箱成可空變量
nullable = (int?)obj;
Console.WriteLine("拆箱成可空變量的情況為:{0}", nullable);

// 裝箱一個沒有值的可空類型的對象
obj = nullablewithoutvalue;
Console.WriteLine("對null的可空類型裝箱后obj 是否為null:{0}", obj==null);

// 拆箱成非可空變量,此時會拋出NullReferenceException異常,因為沒有值的可空類型裝箱后obj等于null,引用一個空地址
// 相當(dāng)于拆箱后把null值賦給一個int 類型的變量,此時當(dāng)然就會出現(xiàn)錯誤了
//value = (int)obj;
//Console.WriteLine("一個沒有值的可空類型裝箱后,拆箱成非可空變量的情況為:{0}", value);

// 拆箱成可空變量
nullable = (int?)obj;
Console.WriteLine("一個沒有值的可空類型裝箱后,拆箱成可空變量是否為null:{0}", nullable == null);
}
運行結(jié)果:

   上面代碼中都有注釋的, 而且代碼也比較簡單, 這里就不解釋了, 其實可空類型的裝箱和拆箱操作大家可以就理解為非可空值類型的裝箱和拆箱的過程,只是對于非可空類型因為包含null值,所以CLR會提前對它進行檢查下它是否為空,為null就不不任何處理,如果不為null,就按照非可空值類型的裝箱和拆箱的過程來裝箱和拆箱。

五、小結(jié)

   到這里本專題的介紹就完成了,本專題主要介紹了下可空類型以及可空類型相關(guān)的知識,希望這篇文章可以幫助大家對可空類型的認識可以更加全面,下一個專題將和大家介紹下匿名方法, 匿名方法也是Lambda表達式和Linq的一個鋪墊,然而它是C#2中被提出來了的, 從而可以看出Lambda和Linq在C# 3.0中被添加其實是微軟早在C# 2.0的時候就計劃好了的,早就計劃好了的(這也是我的推斷,然而我覺得為什么它不直接在把Lambda和Linq都放在C# 2中提出來的, 卻偏偏放在C# 3.0中提出,我理解原因有——1 覺得微軟當(dāng)時肯定是想一起提出的,但是后面發(fā)現(xiàn)這幾個新的特性提出后會對編譯器做比較大的改動,需要比較長的時間來實現(xiàn),此時又怕用戶等不及了,覺得C#很多東西都沒有,所以微軟就先把做好了的部分先發(fā)布出來,然而把Lambda和Linq放到C#3來提出。我推理覺得應(yīng)該是這樣的,所以C#的所有特性都是緊密相連的。)

相關(guān)文章

  • 在winform下實現(xiàn)左右布局多窗口界面的方法

    在winform下實現(xiàn)左右布局多窗口界面的方法

    在web頁面上我們可以通過frameset,iframe嵌套框架很容易實現(xiàn)各種導(dǎo)航+內(nèi)容的布局界面,而在winform、WPF中實現(xiàn)其實也很容易,通過本文給大家介紹在winform下實現(xiàn)左右布局多窗口界面的方法,本文介紹的非常詳細,對winform布局相關(guān)知識感興趣的朋友一起學(xué)習(xí)吧
    2016-02-02
  • C#中的Task使用方式

    C#中的Task使用方式

    本文介紹了C#中的Task,這是一種異步編程模型,允許你在不阻塞主線程的情況下執(zhí)行耗時的操作,文章詳細介紹了如何創(chuàng)建、等待、處理異常、延續(xù)以及并行執(zhí)行Task
    2024-12-12
  • RandomId生成隨機字符串詳解實例

    RandomId生成隨機字符串詳解實例

    本文主要介紹RandomId 生成隨機字符串的方法,大家參考使用吧
    2013-12-12
  • Unity3D動態(tài)對象優(yōu)化代碼分享

    Unity3D動態(tài)對象優(yōu)化代碼分享

    這篇文章主要介紹了Unity3D動態(tài)對象優(yōu)化代碼分享的相關(guān)資料,需要的朋友可以參考下
    2015-03-03
  • 基于C#實現(xiàn)PDF文件合并工具

    基于C#實現(xiàn)PDF文件合并工具

    這篇文章主要為大家詳細介紹了如何基于C#實現(xiàn)一個簡單的PDF文件合并工具,文中的示例代碼簡潔易懂,有需要的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-01-01
  • C#使用Aspose.Cells創(chuàng)建和讀取Excel文件

    C#使用Aspose.Cells創(chuàng)建和讀取Excel文件

    這篇文章主要為大家詳細介紹了C#使用Aspose.Cells創(chuàng)建和讀取Excel文件,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-10-10
  • 詳解c# 數(shù)組(Array)

    詳解c# 數(shù)組(Array)

    這篇文章主要介紹了c# 數(shù)組的的相關(guān)資料,文中講解非常細致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • C# javascript 讀寫Cookie的方法

    C# javascript 讀寫Cookie的方法

    這篇文章介紹了C# javascript 讀寫Cookie的方法,有需要的朋友可以參考一下
    2013-10-10
  • C#封裝將函數(shù)封裝為接口dll的簡單步驟指南

    C#封裝將函數(shù)封裝為接口dll的簡單步驟指南

    在C#中,封裝函數(shù)為接口并打包成DLL是實現(xiàn)代碼重用和模塊化的常見方法,此過程包括創(chuàng)建類庫項目、定義接口、實現(xiàn)接口、編譯項目生成DLL文件,這種方法適用于需要在多個項目間共享功能時使用,需要的朋友可以參考下
    2024-11-11
  • C#?將Excel轉(zhuǎn)為PDF時自定義表格紙張大小的代碼思路

    C#?將Excel轉(zhuǎn)為PDF時自定義表格紙張大小的代碼思路

    這篇文章主要介紹了C#?將Excel轉(zhuǎn)為PDF時自定義表格紙張大小的代碼思路,轉(zhuǎn)換前的頁面大小設(shè)置為該版本中寫入的新功能,在舊版本和免費版本中暫不支持,感興趣的朋友跟隨小編一起看看實例代碼
    2021-11-11

最新評論

牡丹江市| 锡林郭勒盟| 井研县| 黄浦区| 根河市| 商丘市| 横山县| 鞍山市| 黑龙江省| 靖宇县| 台安县| 丰原市| 宜兰市| 南昌市| 巴彦县| 黄龙县| 武功县| 邵阳县| 普兰店市| 任丘市| 东兰县| 嫩江县| 青铜峡市| 连山| 皋兰县| 江山市| 汉中市| 沽源县| 始兴县| 安多县| 长丰县| 万盛区| 扎赉特旗| 莆田市| 大竹县| 兴城市| 东阿县| 凤山市| 云林县| 新竹市| 竹北市|