共用方式為


.NET 8 的 SDK 和工具有什麽新功能

本文會描述 .NET 8 的 .NET SDK 和工具中有何新功能。

SDK

本節包含下列次要主題:

CLI 型專案評估

MSBuild 會包含一項新功能,讓您更輕鬆地將資料從 MSBuild 納入指令碼或工具。 下列新旗標適用於 dotnet publish 這樣的 CLI 命令,以取得資料以供 CI 管線和其他地方使用。

旗標 描述
--getProperty:<PROPERTYNAME> 擷取具有指定名稱的 MSBuild 屬性。
--getItem:<ITEMTYPE> 擷取指定型別的 MSBuild 項目。
--getTargetResults:<TARGETNAME> 從執行指定的目標擷取輸出。

值會寫入至標準輸出。 多個或複雜的值會輸出為 JSON,如下列範例所示。

>dotnet publish --getProperty:OutputPath
bin\Release\net8.0\
>dotnet publish -p PublishProfile=DefaultContainer --getProperty:GeneratedContainerDigest --getProperty:GeneratedContainerConfiguration
{
  "Properties": {
    "GeneratedContainerDigest": "sha256:ef880a503bbabcb84bbb6a1aa9b41b36dc1ba08352e7cd91c0993646675174c4",
    "GeneratedContainerConfiguration": "{\u0022config\u0022:{\u0022ExposedPorts\u0022:{\u00228080/tcp\u0022:{}},\u0022Labels\u0022...}}"
  }
}
>dotnet publish -p PublishProfile=DefaultContainer --getItem:ContainerImageTags
{
  "Items": {
    "ContainerImageTags": [
      {
        "Identity": "latest",
        ...
    ]
  }
}

終端組建輸出

dotnet build 有新選項可產生更現代化的組建輸出。 此終端記錄器輸出會將錯誤與其所來自的專案分組,更能區分多目標專案的不同目標架構,並提供組建作業的即時資訊。 若要選擇加入新的輸出,請使用 --tl 選項。 如需此選項的詳細資訊,請參閱 dotnet 組建選項

簡化的輸出路徑

.NET 8 引進了一個選項,可簡化組建輸出的輸出路徑和資料夾結構。 先前,.NET 應用程式會針對不同的組建成品產生一組具有深度且複雜的輸出路徑。 新的簡化輸出路徑結構則將所有組建輸出收集至一個共用位置,以期使用時更加便利。

如需詳細資訊,請參閱 成品輸出配置

dotnet workload clean 命令

.NET 8 引進了一個新命令,以清除可能經歷數個 .NET SDK 或 Visual Studio 更新後所留下的工作負載套件。 如果您在管理工作負載時遇到問題,請考慮先使用 workload clean 安全地還原至已知狀態,然後再試一次。 此命令有兩個模式:

  • dotnet workload clean

    針對檔案型或 MSI 型工作負載執行工作負載記憶體回收,清除孤立的套件。 孤立的套件來自解除安裝的 .NET SDK 版本或套件安裝記錄已不存在的套件。

    如果已安裝 Visual Studio,此命令也會列出您應該使用 Visual Studio 手動清除的任何工作負載。

  • dotnet workload clean --all

    此模式較積極,會在屬於目前 SDK 工作負載安裝類型的機器上,清除不是來自 Visual Studio 的每個套件。 此命令也會移除正在執行 .NET SDK 功能區及以下項目的所有工作負載安裝記錄。

dotnet publishdotnet pack 資產

由於 dotnet publishdotnet pack 命令的用途是產生生產資產,因此這些命令現在會預設產生 Release 資產。

下列輸出顯示 dotnet builddotnet publish 之間的不同行為,以及如何將 PublishRelease 屬性設定為 false 以還原發佈的 Debug 資產。

/app# dotnet new console
/app# dotnet build
  app -> /app/bin/Debug/net8.0/app.dll
/app# dotnet publish
  app -> /app/bin/Release/net8.0/app.dll
  app -> /app/bin/Release/net8.0/publish/
/app# dotnet publish -p:PublishRelease=false
  app -> /app/bin/Debug/net8.0/app.dll
  app -> /app/bin/Debug/net8.0/publish/

如需詳細資訊,請參閱 'dotnet pack' 使用 Release 組態'dotnet publish' 使用 Release 組態

dotnet restore 安全性稽核

從 .NET 8 開始,您可以在還原相依性套件時,選擇加入已知弱點的安全性檢查。 此稽核會產生安全性弱點的報告,其中包含受影響的套件名稱、弱點的嚴重性,以及用來取得詳細資料的諮詢連結。 當您執行 dotnet adddotnet restore 時,發現任何弱點時會顯示警告 NU1901-NU1904。 如需詳細資訊,請參閱 稽核安全性弱點

範本引擎

範本引擎藉由整合一些 NuGet 的安全性相關功能,在 .NET 8 中提供更安全的體驗。 改善之處包括:

  • 預設會防止從 http:// 摘要下載套件。 例如,由於來源 URL 沒有使用 HTTPS,下列命令將無法安裝範本套件。

    dotnet new install console --add-source "http://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public/nuget/v3/index.json"

    您可以使用 --force 旗標來覆寫這項限制。

  • 針對 dotnet newdotnet new installdotnet new update,請檢查範本套件中的已知弱點。 如果找到弱點,而您想要繼續,則必須使用 --force 旗標。

  • 針對 dotnet new,提供範本套件擁有者的相關資訊。 擁有權會由 NuGet 入口網站驗證,並且可以被認為是值得信賴的特徵。

  • 針對 dotnet searchdotnet uninstall,指出是否從「受信任」的套件安裝範本,也就是說,它會使用保留的前置詞

Source Link 現在會包含在 .NET SDK 中。 目標是藉由將 Source Link 統合至 SDK,而不是針對套件要求個別 <PackageReference>,更多套件會預設包含這項資訊。 此資訊可改善開發人員的 IDE 體驗。

注意

這項變更的副作用是認可資訊會包含在組建程式庫和應用程式的 InformationalVersion 值中,即便以 .NET 7 或舊版為目標也是如此。 如需詳細資訊,請參閱 .NET SDK 中包含的 Source Link

來源組建 SDK

Linux 發行版本組建的 (來源組建) SDK 現在能夠使用來源組建執行階段套件來組建獨立的應用程式。 發行版本特定的執行階段套件會與來源組建 SDK 搭售。 在獨立部署期間,將會參考此搭售的執行階段套件,進而為使用者啟用功能。

支援原生 AOT

在 .NET 7 中首次引進發佈為原生 AOT 的選項。 以原生 AOT 發佈的應用程式會建立完全獨立的應用程式版本,不需要執行階段,所需一切都包含在單一檔案內。 .NET 8 為原生 AOT 發佈帶來下列改進:

  • macOS 上新增 x64 和 Arm64 架構的支援。

  • 將 Linux 上的原生 AOT 應用程式大小減少高達 50%。 下表顯示以原生 AOT 發佈的「Hello World」應用程式大小,該大小包含在 .NET 7 和 .NET 8 上的整個 .NET 執行階段:

    作業系統 .NET 7 .NET 8
    Linux x64 (搭配 -p:StripSymbols=true) 3.76 MB 1.84 MB
    Windows x64 2.85 MB 1.77 MB
  • 可讓您指定最佳化喜好設定: 大小或速度。 根據預設,編譯器會選擇產生快速程式碼,同時留意應用程式的大小。 不過,您可以使用 <OptimizationPreference> MSBuild 屬性,特別針對其中一個或另一個進行最佳化。 如需詳細資訊,請參閱 最佳化 AOT 部署

主控台應用程式範本

預設主控台應用程式範本現在會包含現成的 AOT 支援。 若要建立針對 AOT 編譯設定的專案,只要執行 dotnet new console --aot 即可。 --aot 新增的專案設定具有三個效果:

  • 例如,當您使用 dotnet publish 或 Visual Studio 發行專案時,使用 Native AOT 產生原生獨立可執行檔。
  • 針對修剪、AOT 和單一檔案啟用相容性分析器。 這些分析器會提醒您專案的潛在問題部分 (如果有的話)。
  • 啟用 AOT 的偵錯時間模擬,以便您在沒有 AOT 編譯的情況下偵錯專案時,可獲得與 AOT 類似的體驗。 例如,如果您在未為 AOT 加上註釋 (且因此被相容性分析器遺漏) 的 NuGet 套件中使用 System.Reflection.Emit,則模擬表示當您嘗試使用 AOT 發佈專案時不會有任何意外。

使用原生 AOT 以類似 iOS 的平台為目標

.NET 8 會啟動工作,以啟用類似 iOS 平台的原生 AOT 支援。 您現在可以在下列平台上使用原生 AOT 組建並執行 .NET iOS 和 .NET MAUI 應用程式:

  • ios
  • iossimulator
  • maccatalyst
  • tvos
  • tvossimulator

初步測試顯示,對於使用原生 AOT 而非 Mono 的 .NET iOS 應用程式,磁碟上的應用程式大小會減少約 35%。 .NET MAUI iOS 應用程式的磁碟上應用程式大小最多可減少 50%。 此外,啟動時間也更快。 .NET iOS 應用程式啟動時間快約 28%,而與 Mono 相比, .NET MAUI iOS 應用程式的啟動效能高出約 50%。 .NET 8 支援是實驗性的,而且只是整個功能的第一個步驟。 如需詳細資訊,請參閱 .NET MAUI 中的 .NET 8 效能改進部落格文章

原生 AOT 支援可作為用於應用程式部署的選擇加入功能;Mono 仍然是應用程式開發和部署的預設執行階段。 若要在 iOS 裝置上使用原生 AOT 組建並執行 .NET MAUI 應用程式,請使用 dotnet workload install maui 來安裝 .NET MAUI 工作負載以及使用 dotnet new maui -n HelloMaui 來建立應用程式。 然後,將專案檔中的 MSBuild 屬性 PublishAot 設定為 true

<PropertyGroup>
  <PublishAot>true</PublishAot>
</PropertyGroup>

當您設定必要的屬性並如下列範例所示執行 dotnet publish 時,將會使用原生 AOT 來部署應用程式。

dotnet publish -f net8.0-ios -c Release -r ios-arm64  /t:Run

限制

並非所有 iOS 功能都與原生 AOT 相容。 同樣地,並非所有在 iOS 中常用的程式庫都與 NativeAOT 相容。 除了原生 AOT 部署的現有限制之外,下列清單也會在以類似 iOS 的平台為目標時顯示一些其他限制:

  • 使用原生 AOT 只有在應用程式部署 (dotnet publish) 期間才會啟用。
  • 只有 Mono 才支援受控程式碼偵錯。
  • 與 .NET MAUI 架構的相容性有限。

Android 應用程式的 AOT 編譯

為了減少應用程式大小,以 Android 為目標的 .NET 和 .NET MAUI 應用程式會在發行模式中組建時使用已分析的預先 (AOT) 編譯模式。 與一般 AOT 編譯相比,已分析的 AOT 編譯會影響較少的方法。 .NET 8 會引進 <AndroidStripILAfterAOT> 屬性,讓您選擇加入更多 Android 應用程式的 AOT 編譯,以進一步減少應用程式大小。

<PropertyGroup>
  <AndroidStripILAfterAOT>true</AndroidStripILAfterAOT>
</PropertyGroup>

根據預設,將 AndroidStripILAfterAOT 設定為 true 會覆寫預設 AndroidEnableProfiledAot 設定,允許修剪已編譯 AOT 的 (幾乎) 所有方法。 您也可以藉由將這兩個屬性明確地設定為 true,將已分析的 AOT 和 IL 裁剪一起使用:

<PropertyGroup>
  <AndroidStripILAfterAOT>true</AndroidStripILAfterAOT>
  <AndroidEnableProfiledAot>true</AndroidEnableProfiledAot>
</PropertyGroup>

跨組建的 Windows 應用程式

當您在非 Windows 平台上組建以 Windows 為目標的應用程式時,產生的可執行檔現在會以任何指定的 Win32 資源進行更新,例如應用程式圖示、資訊清單、版本資訊。

先前,應用程式必須組建在 Windows 上才能有這類資源。 一直收到許多要求在跨組建支援中修正這個差距,因為它是影響基礎結構複雜度和資源使用量的致命痛點。

Linux 上的 .NET

Linux 的最低支援基準

Linux 的最低支援基準已針對 .NET 8 更新。 .NET 是針對所有架構以 Ubuntu 16.04 為目標所組建。 這主要對於定義 .NET 8 的最低 glibc 版本而言非常重要。 .NET 8 無法在包含舊版 glibc 的發行版本上啟動,例如 Ubuntu 14.04 或 Red Hat Enterprise Linux 7。

如需詳細資訊,請參閱 Red Hat Enterprise Linux 系列支援

在 Linux 上組建您自己的 .NET

在舊版 .NET 中,您可以從來源組建 .NET,但您必須從對應至版本的 dotnet/installer 存放庫認可建立「來源 tarball」。 在 .NET 8 中,您不再需要這麽做,您可以直接從 dotnet/dotnet 存放庫在 Linux 上組建 .NET。 該存放庫會使用 dotnet/source-build 組建 .NET 執行階段、工具和 SDK。 此組建與 Red Hat 和 Canonical 用來建立 .NET 的組建相同。

對大多數人而言,在容器中建立是最簡單的方法,因為 dotnet-buildtools/prereqs 容器映像包含所有必要的相依項。 如需詳細資訊,請參閱建置指示

NuGet 簽章驗證

從 .NET 8 開始,NuGet 預設會在 Linux 上驗證已簽署的套件。 NuGet 也會持續驗證 Windows 上已簽署的套件。

大部分的使用者不會注意到驗證。 不過,如果您有位於 /etc/pki/ca-trust/extracted/pem/objsign-ca-bundle.pem 的現有根憑證搭售方案,您可能會看到信任失敗,並出現警告 NU3042

您可以將環境變數 DOTNET_NUGET_SIGNATURE_VERIFICATION 設定為 false,以選擇退出驗證。

程式碼分析

.NET 8 包含數個新的程式碼分析器和修正程式,可協助確認您正確且有效率地使用 .NET 程式庫 API。 下表摘要說明新的分析器。

規則識別碼 類別 描述
CA1856 效能 在參數上未正確套用 ConstantExpectedAttribute 屬性時引發。
CA1857 效能 當參數加上 ConstantExpectedAttribute 註釋但提供的引數不是常數時引發。
CA1858 效能 若要判斷字串是否以指定的前置詞開頭,最好呼叫 String.StartsWith 而不是呼叫 String.IndexOf,然後將結果與零進行比較。
CA1859 效能 此規則建議盡可能將特定區域變數、欄位、屬性、方法參數和方法傳回型別從介面或抽象型別升級為具體型別。 使用具體型別會導致產生品質較高的程式碼。
CA1860 效能 若要判斷集合型別是否有任何元素,最好是使用 LengthCountIsEmpty 來呼叫 Enumerable.Any
CA1861 效能 當重複呼叫時,傳遞為引數的常數陣列不會重複使用,這表示每次都會建立新的陣列。 若要改善效能,請考慮將陣列擷取至靜態唯讀欄位。
CA1865-CA1867 效能 Char 多載是針對具有單一 Char 字串效能較佳的多載。
CA2021 可靠性 Enumerable.Cast<TResult>(IEnumerable)Enumerable.OfType<TResult>(IEnumerable) 需要相容的型別才能正常運作。 泛型型別不支援擴大和使用者定義轉換。
CA1510-CA1513 可維護性 擲回協助程式比建構新例外狀況執行個體的 if 區塊更簡單且更有效率。 已針對下列例外狀況建立這四個分析器: ArgumentNullExceptionArgumentExceptionArgumentOutOfRangeExceptionObjectDisposedException

診斷

C# 熱重新載入支援修改泛型

從 .NET 8 開始,C# 熱重新載入支援修改泛型型別和泛型方法。 當您使用 Visual Studio 對控制台、桌面、行動裝置或 WebAssembly 應用程式進行偵錯時,可以在 C# 程式碼或 Razor 頁面中將變更套用至泛型型別和泛型方法。 如需詳細資訊,請參閱 Roslyn 所支援編輯的完整清單

另請參閱