日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無先后,達(dá)者為師

網(wǎng)站首頁 編程語言 正文

C#新特性之可空引用類型_C#教程

作者:Sweet-Tang ? 更新時(shí)間: 2022-04-26 編程語言

安裝

您必須下載Visual Studio 2017 15.5預(yù)覽版(目前最新發(fā)布版本是15.4),下載地址:https://www.visualstudio.com/en-us/news/releasenotes/vs2017-preview-relnotes。

安裝Roslyn擴(kuò)展預(yù)覽版本:

  • 下載并解壓 Roslyn_Nullable_References_Preview.zip?[最新版本 11/15/17];
  • 關(guān)閉所有運(yùn)行的Visual Studio;
  • 運(yùn)行zip根目錄中的 .\install.bat 腳本(如果需要卸載擴(kuò)展,可以運(yùn)行.\uninstall.bat腳本);

語法與類型

在語法上,可為空引用類型與可為空值類型使用的語法是一致的,在類型后面追加???即可。

class Person
{
    public string FirstName;   
    public string? MiddleName; 
    public string LastName;
}

我們都知道當(dāng)初微軟在增加可為空值類型的時(shí)候,實(shí)際是在框架中增加了System.Nullable<>類型,您肯定會(huì)問,可為空引用類型以框架中又增加了什么新的類型。

我們來看一個(gè)演示:

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(typeof(string?).FullName);
        }
    }

輸出結(jié)果:

您是否覺得奇怪,怎么輸出的是System.String,是的,其實(shí)微軟在框架中沒有加入任何類型,我們Person類型進(jìn)行編譯后,再通過dotPeek進(jìn)行反編譯,就明白到底發(fā)生了什么。

反編譯后的結(jié)果:

    internal class Person
    {
        public string FirstName;
        [Nullable]
        public string MiddleName;
        public string LastName;
    }

只是在MiddleName字段上增加了System.Runtime.CompilerServices.NullableAttribute標(biāo)記。

我們來看一看屬性、參數(shù)、變量、返回值編譯之前與編譯之后的比對(duì)結(jié)果。

屬性

    // 編譯前:
    public string? MiddleName { get; set; }  
  
    // 編譯后:
    [Nullable]
    public string MiddleName { [return: Nullable] get; [param: Nullable] set; }

參數(shù)

    // 編譯前:
    public Person(string? middleName )
    {
        this.MiddleName = middleName;
    }

    // 編譯后:
    public Person([Nullable] string middleName)
    {
      this.MiddleName = middleName;
    }

返回值

    // 編譯前:
    public string? DoSomething()
    {
        return null;
    }

    // 編譯后:
    [return: Nullable]
    public string DoSomething()
    {
      return (string) null;
    }

變量

    // 編譯前:
    string? name;

    // 編譯后:
    string name;

這里除了變量,其它的都使用了NullableAttribute標(biāo)記進(jìn)行的修飾。

它可以做什么?

通過上面的章節(jié),我們知道,可為空引用類型只是在參數(shù)、屬性、參數(shù)和返回值中使用NullableAttribute標(biāo)記進(jìn)行修飾,實(shí)際上對(duì)程序的正常運(yùn)行沒有任何的影響。那么它可以為我們做什么呢?

表達(dá)意圖

在C#中不能表達(dá)這個(gè)變量、參數(shù)、字段、屬性,返回值等可能為null或不能為null,可為空類型可以幫我們解決這個(gè)問題。

    class Person
    {
        public string FirstName;   // 不為null
        public string? MiddleName; // 可能為null
        public string LastName;    // 不為null
    }

這個(gè)類型的可以表示每一個(gè)人都應(yīng)該?FristName?和?LastName?,但是不是每一個(gè)人都應(yīng)該有?MiddleName。

編譯器檢測(cè)

可為空引用類型的另一個(gè)好處是編譯器可以幫助我們檢測(cè)代碼,比如對(duì)于直接使用可為空引用類型的屬性,編譯器會(huì)發(fā)出警告。

    void M(Person p)
    {
        p.FirstName = null;          // 1 WARNING: Cannot convert null to non-nullable reference。
        p.LastName = p.MiddleName;   // 2 WARNING: Possible null reference assignment.
        string s = default(string);  // 3 WARNING: Cannot convert null to non-nullable reference。
        
        if (p.MiddleName != null) 
        {
            WriteLine(p.MiddleName.Length); // ok
        }
        
         WriteLine(p.MiddleName!.Length); // ok
    }
    
    class Person
    {
        public string FirstName;     // 4 WARNING: Non-nullable field 'FirstName' is uninitialized.
        public string? MiddleName; 
        public string LastName;      // 5 WARNING: Non-nullable field 'LastName' is uninitialized.
    }

編譯器會(huì)幫我們做以下幾點(diǎn)檢測(cè):

  • 如果給非可為空引用類型賦null值或可為空引用類型的值,則會(huì)發(fā)出警告;
  • 如果直接使用可為空引用類型,則會(huì)發(fā)出警告;
  • 如果從來沒有給非可為空引用類型的屬性賦值,則會(huì)發(fā)出警告;
  • 如果需要直接使用可為空引用類型,需要使用?!?符號(hào)告訴編譯器,您已經(jīng)確認(rèn)過該值不可能為空。

當(dāng)然這只是編譯器的行為,可以禁用與之相關(guān)的警告提示。

總結(jié)

空引用類型是一個(gè)語法糖,只是在編譯器的層面幫我們發(fā)現(xiàn)可能發(fā)生的問題,對(duì)程序的正常運(yùn)行沒有任何作用。

原文鏈接:https://www.cnblogs.com/tdfblog/p/Nullable-Reference-Types-Preview.html

欄目分類
最近更新