天天看點

C# 8 - Nullable Reference Types 可空引用類型

在寫C#代碼的時候,你可能經常會遇到這個錯誤: 

但如果想避免NullReferenceException的發生,确實需要做很多麻煩的工作。 

是以,C# 8的可空引用類型就出現了。 

C# 8可以讓你在編譯時就避免null引用錯誤,它并不是把null值從代碼裡移除了,而是它可以讓你表達意圖。具體的做法就是你可以告訴編譯器哪個引用可能是null的,而哪些引用不可能是null。 

看下面這個例子: 

很顯然,我們期待person這個參數它不可以是null的。 

但是在C# 8之前,如果我們這樣調用該方法,那麼在編譯時是不會報錯的: 

而如果運作程式,那麼結果就是: 

而在Visual Studio 2019裡面(C# 8的項目),修改項目檔案,添加null檢查之後: 

這裡就會出現警告。 

有兩個類,Person類的Address屬性的類型是另外一個類: 

現在可以看到,這些屬性都出現了波浪線的警告,如果我們build一下這個項目,那麼也會出現很多警告: 

這是因為我們把這兩個類的成員聲明稱了非null的引用類型,而我卻沒有對它們進行初始化。 

如果我想讓這些成員可以為null(意圖上),那麼就需要把它們設定為可null的(意圖),在類型後邊加上問号“?”即可: 

再次build項目之後,警告都沒有了: 

然後再看一下這個方法: 

這裡person.Address.Province有一個警告,是因為Address可能是null。 

可以有幾種辦法把這個警告去掉,首先是使用null條件操作符: 

如果是Address是null的話,就輸出null。 

或者,如果你确認Address屬性不會是null,那麼可以在Address後添加一個歎号”!“,表示Address肯定不是null: 

這個歎号的作用僅僅是去掉了警告,它沒有改變任何運作時的狀況,如果Address為null,那麼這句話仍然會抛出NullReferenceException。 

是以,隻有确認我們通路的東西肯定不是null的時候,才應該使用"!"。 

下面我更改一下思路意圖,假設所有的成員都不可能為null,那麼修改兩個類: 

類成員又出現了警告。 

而回到方法裡,我把歎号和問号都去掉之後,也不會出現警告了,因為它認為所有的成員都不會是null了: 

但是還要記住,這個隻是在編譯時進行的檢查,如果成員為null,還是會抛出異常的。這種操作對于運作時來說沒有任何改變。 

解決成員上出現的警告 

使用構造函數對成員初始化,可以去掉這些警告: 

另外一種辦法就是直接對屬性進行初始化: 

我們還是采用構造函數初始化的辦法吧。 

那麼往構造函數裡面傳遞null會出現什麼情況呢?試一下: 

提示還是比較智能的,有警告,它說無法把null這個字面值轉化為非null的引用類型。 

如果把老項目的項目檔案直接添加以下内容: 

那麼項目在編譯的時候很可能出現大規模的問題。 

是以一點一點啟用nullable檢查是比較好的做法。 

首先我把項目檔案恢複原狀,然後打開某個檔案,在檔案最上面添加以下内容: 

然後在檔案的最下面添加: 

這樣的話,這個檔案裡面所有的内容都開起了nullable檢查。 

或者,我們也可以隻針對一段代碼進行檢查: 

C# 8 - Nullable Reference Types 可空引用類型
下一篇: makefile