溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

.NET中可空值類型Nullable<T>的示例分析

發(fā)布時(shí)間:2021-07-12 09:55:28 來源:億速云 閱讀:115 作者:小新 欄目:開發(fā)技術(shù)

這篇文章給大家分享的是有關(guān).NET中可空值類型Nullable<T>的示例分析的內(nèi)容。小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過來看看吧。

為了讓.Net中的值類型可以賦值為null,微軟特地添加了Nullable<T>類型,也可簡(jiǎn)寫為T?。但是Nullable<T>自身是結(jié)構(gòu)體,也是值類型,那么它是如何實(shí)現(xiàn)將null賦值給值類型的呢?

下面通過自定義一個(gè)可空值類型來講解Nullable<T>的實(shí)現(xiàn)原理。

自定義可空值類型

struct XfhNullable<T> where T : struct
{
  private T innerValue;
  //這個(gè)屬性很重要
  public bool HasValue { set; get; }
  public T Value
  {
    get
    {
      return HasValue ? innerValue: throw new InvalidOperationException();
    }
  }
  public XfhNullable(T value)
  {
    this.innerValue= value;
    HasValue = true;
  }
  public T GetValueOrDefault(T value)
  {
    return HasValue ? this.innerValue: value;
  }
  public T GetValueOrDefault()
  {
    return this.innerValue;
  }
}

一個(gè)可空值類型的結(jié)構(gòu)體大致功能已經(jīng)定義好了,下面我們來創(chuàng)建可空值類型的實(shí)例來驗(yàn)證下。

using static System.Console;
class Program
{
  static void Main()
  {
    //使用結(jié)構(gòu)體默認(rèn)的無參構(gòu)造函數(shù)進(jìn)行實(shí)例化
    XfhNullable<int> num = new XfhNullable<int>();
    WriteLine(num.HasValue);
    WriteLine(null_num.GetValueOrDefault());
  }
}

.NET中可空值類型Nullable<T>的示例分析

可以看到,變量num并不含有值,調(diào)用GetValueOrDefault()則會(huì)獲取它的默認(rèn)值 0;

這時(shí)我們將null賦值給變量num會(huì)發(fā)現(xiàn)編譯器報(bào)錯(cuò)Cannot convert null to 'XfhNullable<int>' because it is a non-nullable value type這是因?yàn)榫幾g器把我們定義的結(jié)構(gòu)體XfhNullable<T>看作是普通值類型而非可空值類型,所以我們還要添加可空值類型和XfhNullable<T>之間的轉(zhuǎn)換功能。

public static implicit operator XfhNullable<T>(T? nullabelValue)
{
  if (nullabelValue== null)
  {
    return new XfhNullable<T>();
  }
  return new XfhNullable<T>(nullabelValue.Value);
}

上面的代碼實(shí)現(xiàn)了可空值類型向XfhNullable<T>的隱式轉(zhuǎn)換,添加上面代碼之后發(fā)現(xiàn)編譯器不再報(bào)錯(cuò)。XfhNullable<T>已經(jīng)成為一個(gè)可為null的值類型。

static void Main()
{
  XfhNullable<int> null_num = null;
  WriteLine(null_num.HasValue);
}

.NET中可空值類型Nullable<T>的示例分析

XfhNullable<T>中的屬性HasValue的作用就是標(biāo)記當(dāng)前類型是否為null,若是則返回False,否則返回True。當(dāng)HasValue為False時(shí)調(diào)用該類型的Value屬性則會(huì)拋出異常InvalidOperationException。但可調(diào)用GetValueOrDefault()方法來獲取類型的默認(rèn)值。

Nullable<T>類型可以通過運(yùn)算符==來判斷值是否為null,我們也可以通過運(yùn)算符重載來實(shí)現(xiàn)該功能:

public static bool operator ==(XfhNullable<T> cn, object obj)
{
  if (cn.HasValue)
  {
    return false;
  }
  return true;
}
public static bool operator !=(XfhNullable<T> cn, object obj)
{
  return !(cn == obj);
}
static void Main()
{
  XfhNullable<int> null_num = null;
  WriteLine(null_num == null);
}

.NET中可空值類型Nullable<T>的示例分析

接下來,我們來實(shí)現(xiàn)普通值類型和XfhNullable<T>之間的轉(zhuǎn)換:

public static implicit operator XfhNullable<T>(T value)
{
  return new XfhNullable<T>(value);
}
public static explicit operator T(XfhNullable<T> value)
{
  return value.innerValue;
}
static void Main()
{
  XfhNullable<int> null_num = null;
  null_num = 12;//int類型隱式轉(zhuǎn)換為XfhNullable<int>類型
  WriteLine(null_num == null);
  WriteLine(null_num.Value);
  int i = (int)null_num;//XfhNullable<int>類型強(qiáng)制轉(zhuǎn)換為int類型
  WriteLine(i);
}

.NET中可空值類型Nullable<T>的示例分析

獲取實(shí)例在運(yùn)行時(shí)的類型:

static void Main()
{
  XfhNullable<int> null_num = 12;
  WriteLine(null_num.GetType());
}

.NET中可空值類型Nullable<T>的示例分析

這個(gè)返回值不大友好,我們希望這里返回內(nèi)置的值類型,System.Int32,具體實(shí)現(xiàn)代碼如下:

//因?yàn)镺bject類中的GetType方法不允許子類重寫(避免子類隱藏自己的實(shí)際類型)
//所以這里使用關(guān)鍵字new來隱藏Object類中的GetType方法
public new Type GetType()
{
  return innerValue.GetType();
}

.NET中可空值類型Nullable<T>的示例分析

結(jié)論:沒有可為空的值類型

至此,我們已經(jīng)自定義了一個(gè)可為空的值類型XfhNullable<T>,通過以上代碼,我們不難發(fā)現(xiàn)所謂可為空的值類型是不存在的,它是通過屬性HasValue來對(duì)null值進(jìn)行標(biāo)記的,其內(nèi)部通過字段innerValue(該字段對(duì)應(yīng)Nullable<T>中的value字段)來維護(hù)該類型的值,若被賦值為null則innerValue初始化為值類型的初始值。換句話說,Nullable<T>只是在邏輯層面上實(shí)現(xiàn)了把null賦值給值類型,給我們一種值類型可為null的感覺。

最后說下可空值類型的裝箱與拆箱。

CLR在對(duì)Nullable<T>實(shí)例執(zhí)行裝箱操作時(shí)首先檢查它是否為null,若是則CLR不裝箱任何東西而是直接返回null;若實(shí)例的值不是null則獲取該實(shí)例的值(Value屬性)并對(duì)這個(gè)值進(jìn)行裝箱操作。

拆箱時(shí),對(duì)于null則返回一個(gè)Nullable<T>()實(shí)例,對(duì)于一個(gè)具體的數(shù)值,如5,則返回Nullable<T>(5)實(shí)例。

感謝各位的閱讀!關(guān)于“.NET中可空值類型Nullable<T>的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI