在.NET框架中使用C# 8和可空引用類型

本文要點:

  • 改變C#版本需要直接修改項目文件
  • 全局啓用可空引用類型只能在新的項目格式中實現
  • 可根據需要,在文件或行的基礎上更改可空性
  • 使用可空屬性以避免不必要的空檢查。
  • 針對較舊的平臺時,可使用Nullable包

儘管在.NET 框架中,C# 8的一部分將永遠不會得到支持,但是,如果我們知道一些技巧的話,那麼可以啓用可空引用類型

啓用C# 8

第一步是確保我們使用的是Visual Studio 2019 16.3版或更高版本。

然後,我們需要爲C# 8配置我們的項目。如果我們習慣使用Visual Studio的話,那麼,我們可能期望能夠簡單地更改項目設置。不幸的是,那種方式已經無效了。

在新規則下,C#的默認版本由我們要面向的框架決定。只有.NET Core 3.0和.NET Standard 2.1可以用C# 8 ,其他的都從C# 7.3版本開始。

我們可以通過編輯項目文件來覆蓋它。打開項目的.csproj文件,並在PropertyGroup中添加下面這行代碼:

<LangVersion>8.0</LangVersion>

如果我們使用現代項目格式的話,那麼,在解決方案資源管理器(Solution Explorer)中雙擊該項目就可以將其打開。我們可以識別出這個格式,因爲XML文件看起來是這樣的:

<Project Sdk="Microsoft.NET.Sdk">

如果我們使用遺留項目格式的話,那麼,直接編輯它有點複雜。可以選擇關閉Visual Studio,使用Notepad或其他文本編輯器。或者,我們可以安裝Visual Studio的Power Commands,它會添加一個“Edit Project File”命令。作爲參考,XML文件的根看起來類似這個:

<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

啓用可空引用類型:

接下來是啓用可空引用類型功能。如果我們使用現代項目格式的話,那麼,我們可以通過在語言版本的後面添加如下所示的代碼行來全局化實現這一點:

<Nullable>enable</Nullable>

如果我們使用遺留項目格式的話,那麼,這樣做就不起作用。我們不會得到錯誤提示,編譯器只是忽略這個設置。因此,我們必須逐個文件地啓用它。要做到這一點,必須在每個文件的頂部添加可空指令:

#nullable enable

如果我們希望逐步啓用該功能,那麼,在現代項目中也可以這麼做。

可空性屬性

有各種各樣的屬性可用於微調空檢查器的行爲。爲了解釋該功能,可以考慮如下函數:

bool TryGet(int key, out Customer? customer)

隱含的約定是,如果該函數返回true,那麼,customer參數將不爲空。反之,如果該函數返回false,那麼,customer參數將爲空。

但是,這不是簽名的一部分,因此,如果我們要這樣使用這個函數,那麼,我們就總是需要在customer上進行一個無關的空檢查。解決方法是,添加一個闡明行爲的屬性:

bool TryGet(int key, [NotNullWhen(true)] out Customer? customer)

從編譯器的角度來看,這意味着,如果返回true,那麼,customer將永遠不會是空值。如果返回的是false,它沒有說明會發生什麼情況,但是,這仍然足以解決簽名問題了。

在《嘗試可空引用類型》這篇文章中,Phillip Carter詳細地描述了各種屬性:

  • 條件化的後置條件:MaybeNotNullWhen(bool)、 NotNullWhen(bool)
  • 依賴是非爲空:NotNullIfNotNull
  • 流:DoesNotReturn、DoesNotReturnIf(bool)
  • 後置條件:MaybeNull、NotNull
  • 前置條件:AllowNull、DisallowNull

舊項目中的可空性屬性

爲了實際使用這些屬性,需要定義它們。如果我們在使用.NET Standard 2.1或.NET Core 3.0的話,那麼,這些已經是現成的了。否則,我們將不得不創建它們,把它們作爲我們項目的一部分。

處理這個問題的傳統方式是創建一個新的.NET Core 3項目,使用F12對所需的屬性進行反向工程。然後,我們可以把它粘貼到我們的項目上,並添加缺少的細節,對於屬性來說,這只需要幾分鐘時間。

一種更簡單的方法是,簡單地安裝Maunel Römer的Nullable包。這將把NullableAttributes.cs 文件複製到我們的項目中,其中包括所有必需的屬性。這個包沒有編譯過的組件,只是一個源代碼文件。

這兩種方法都要確保所有的屬性被標記成“內部”,而不是公共。這是爲了避免與也可能向後移植屬性的其他庫發生衝突。

作者介紹

Johathan Allen於90年代後期開始爲一家醫療診所開發MIS項目,逐步地將它們從Access和Excel提升到企業解決方案。在爲金融行業編寫了5年自動交易系統後,他成了多個項目的顧問,這些項目包括機器人倉庫的UI、癌症研究軟件的中間層以及一家大型房地產保險公司的大數據需求。在業餘時間,他熱衷於對16世紀的武術進行研究及相關的寫作。

原文鏈接:

Using C# 8 and Nullable Reference Types in .NET Framework

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章