在寫C#代碼的時候,你可能常常會遇到這個錯誤: session
但若是想避免NullReferenceException的發生,確實須要作不少麻煩的工做。 app
因此,C# 8的可空引用類型就出現了。 函數
C# 8可讓你在編譯時就避免null引用錯誤,它並非把null值從代碼裏移除了,而是它可讓你表達意圖。具體的作法就是你能夠告訴編譯器哪一個引用多是null的,而哪些引用不多是null。 ui
看下面這個例子: spa
很顯然,咱們期待person這個參數它不能夠是null的。 orm
可是在C# 8以前,若是咱們這樣調用該方法,那麼在編譯時是不會報錯的: xml
而若是運行程序,那麼結果就是: ci
而在Visual Studio 2019裏面(C# 8的項目),修改項目文件,添加null檢查以後: get
這裏就會出現警告。 編譯器
有兩個類,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檢查。
或者,咱們也能夠只針對一段代碼進行檢查: