.NET Core 3.0 的新功能

本文描述 .NET Core 3.0 的新功能。 其中一個最大的增強功能是對 Windows 傳統型應用程式的支援 (僅限 Windows)。 您可以使用 .NET Core 3.0 SDK 元件「Windows 傳統型」來移植 Windows Forms 和 Windows Presentation Foundation (WPF) 應用程式。 具體而言,只有在 Windows 上才支援並包含「Windows 傳統型」元件。 如需詳細資訊,請參閱本文稍後的 Windows 傳統型一節。

.NET Core 3.0 新增 C# 8.0 支援。 強烈建議您使用 Visual Studio 2019 16.3 版或更新版本、Visual Studio for Mac 8.3 或更新版本,或具備最新 C# 延伸模組Visual Studio Code

立即在 Windows、macOS 或 Linux 上下載並開始使用 .NET Core 3.0

如需版本的詳細資訊,請參閱 .NET Core 3.0 公告

.NET Core 3.0 RC 1 已由 Microsoft 視為生產環境就緒,並獲得完整支援。 如果您使用預覽版本,您必須移至 RTM 版本,才能繼續獲得支援。

語言改善 C# 8.0

C# 8.0 也是此版本的一部分,其中包含可為 Null 的參考型別功能、非同步流程和其他模式。 如需 C# 8.0 功能的詳細資訊,請參閱 C# 8.0 的新功能

C# 8.0 語言功能的教學課程:

已新增語言增強功能,以支援下列 API 功能,詳述如下:

.NET Standard 2.1

.NET Core 3.0 實作 .NET Standard 2.1。 不過,預設 dotnet new classlib 範本會產生仍以 .NET Standard 2.0 為目標的專案。 若要以 .NET Standard 2.1 為目標,請編輯您的專案檔並將 TargetFramework 屬性變更為 netstandard2.1

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

  <PropertyGroup>
    <TargetFramework>netstandard2.1</TargetFramework>
  </PropertyGroup>

</Project>

如果目前使用 Visual Studio,您需要 Visual Studio 2019,因為 Visual Studio 2017 不支援 .NET Standard 2.1.NET Core 3.0

編譯/部署

預設可執行檔

.NET Core 現在預設會建置架構相依可執行檔。 這對於使用 .NET Core 全域安裝版本的應用程式來說,是一項新行為。 先前,只有獨立式部署會產生可執行檔。

dotnet builddotnet publish 期間,會建立符合您所用 SDK 環境和平台的可執行檔 (稱為 appHost)。 針對這些可執行檔,您可以預期能夠進行與其他原生可執行檔相同的操作,例如:

  • 您可以按兩下可執行檔。
  • 您可以直接從命令提示字元啟動應用程式,例如在 Windows 上為 myapp.exe,在 Linux 和 macOS 上為 ./myapp

macOS appHost 和 notarization

僅限 macOS

從對於 macOS 已經過公證的 .NET Core SDK 3.0 開始,預設會停用產生預設可執行檔 (稱為 appHost) 的設定。 如需詳細資訊,請參閱 macOS Catalina Notarization 及對 .NET Core 下載和專案的影響

啟用 appHost 設定時,.NET Core 會在您建置或發佈時產生原生 Mach-O 可執行檔。 當您的應用程式透過 dotnet run 命令從原始程式碼中執行,或透過直接啟動 Mach-O 可執行檔時,您的應用程式會在 appHost 的內容中執行。

如果沒有 appHost,使用者可啟動架構相依應用程式的唯一方法是使用 dotnet <filename.dll> 命令。 當您發佈獨立式應用程式時,一律會建立 appHost。

您可以在專案層級設定 appHost,或針對 appHost 切換成使用含 -p:UseAppHost 參數的特定 dotnet 命令:

  • 專案檔

    <PropertyGroup>
      <UseAppHost>true</UseAppHost>
    </PropertyGroup>
    
  • 命令列參數

    dotnet run -p:UseAppHost=true
    

如需 UseAppHost 設定的詳細資訊,請參閱 Microsoft.NET.Sdk 的 MSBuild 屬性

單一檔案可執行檔

dotnet publish 命令支援將您的應用程式封裝成平台特定單一檔案可執行檔。 可執行檔會自我解壓縮,並包含執行應用程式所需的所有相依性 (包括原生)。 第一次執行應用程式時,系統會將應用程式解壓縮到以應用程式名稱和組建識別碼為基礎的目錄。 再次執行應用程式時的啟動速度會更快。 除非使用新版本,否則應用程式不需要再次自我解壓縮。

若要發佈單一檔案可執行檔,請在專案中或在命令列上使用 dotnet publish 命令來設定 PublishSingleFile

<PropertyGroup>
  <RuntimeIdentifier>win10-x64</RuntimeIdentifier>
  <PublishSingleFile>true</PublishSingleFile>
</PropertyGroup>

-或-

dotnet publish -r win10-x64 -p:PublishSingleFile=true

如需單一檔案發佈的詳細資訊,請參閱單一檔案搭配程式設計文件

組件修剪

.NET Core 3.0 SDK 隨附能透過分析 IL 並修剪未使用的組件來減少應用程式大小的工具。

自封式應用程式包含執行程式碼所需的一切項目,因此不需要在主機電腦上安裝 .NET。 不過,應用程式經常只需要一小部分的架構子集便能運作,而其他未使用的程式庫則可以被移除。

.NET Core 現在包含會使用 IL 修剪器工具來掃描應用程式 IL 的設定。 此工具會偵測所需的程式碼,然後修剪未使用的程式庫。 此工具可以大幅減少某些應用程式的部署大小。

若要啟用此工具,請在專案中新增 <PublishTrimmed> 設定,並發佈獨立式應用程式:

<PropertyGroup>
  <PublishTrimmed>true</PublishTrimmed>
</PropertyGroup>
dotnet publish -r <rid> -c Release

例如,所包含的基本 "hello world" 新主控台專案在發佈時的大小大約是 70 MB。 透過使用 <PublishTrimmed>,該大小會被縮減為大約 30 MB。

請務必記得,對使用反映或相關動態功能的應用程式或架構 (包括 ASP.NET Core 和 WPF) 進行修剪經常會發生中斷的情況。 會發生此中斷的原因是因為修剪器不知道此動態行為,因此無法判斷反映所需的架構類型有哪些。 可以對 IL 修剪器工具加以設定來使其注意到此情況。

無論如何,請務必在修剪後測試您的應用程式。

如需 IL 修剪器工具的詳細資訊,請參閱文件 \(英文\) 或造訪 mono/linker \(英文\) 存放庫。

階層式編譯

.NET Core 3.0 預設會開啟階層式編譯 (TC)。 這項功能可讓執行階段更彈性地使用 Just-In-Time (JIT) 編譯器來達到更佳的效能。

階層式編譯的主要優點是提供兩種方式的編譯方法:在較低品質但較快的等級或較高品質但較慢的階層中。 品質是指方法的最佳化程度。 由於行經各種執行階段 (從啟動到穩定狀態),因此 TC 有助於改善應用程式的效能。 停用階層式編譯時,每個方法都會以單一方式編譯,以偏向於啟動效能的穩定狀態效能。

啟用 TC 時,下列行為適用於應用程式啟動時的方法編譯:

  • 如果方法具有預先編譯的程式碼 (ReadyToRun),則會使用預先產生的程式碼。
  • 否則,方法會經過編譯。 一般而言,這些方法是實值型別的泛型。
    • 快速 JIT 會更快速地產生品質較低的 (或較不最佳化的) 程式碼。 在 .NET Core 3.0 中,預設會針對不包含迴圈且在啟動期間慣用的方法啟用快速 JIT。
    • 完全最佳化 JIT 會產生更高品質的 (或更最佳化的) 程式碼速度較慢。 例如,對於不會使用 Quick JIT 的方法 (例如,如果方法是以 MethodImplOptions.AggressiveOptimization 設定屬性),則會使用完全最佳化 JIT。

針對經常呼叫的方法,Just-In-Time 編譯器最終會在背景中建立完全最佳化的程式碼。 最佳化程式碼接著會取代該方法的預先編譯器程式碼。

快速 JIT 所產生的程式碼可能會執行較慢、配置更多記憶體,或使用更多堆疊空間。 如果發生問題,您可以在專案檔中使用這個 MSBuild 屬性停用 Quick JIT:

<PropertyGroup>
  <TieredCompilationQuickJit>false</TieredCompilationQuickJit>
</PropertyGroup>

若要完全停用 TC,請在您的專案檔中使用此 MSBuild 屬性:

<PropertyGroup>
  <TieredCompilation>false</TieredCompilation>
</PropertyGroup>

提示

如果您在專案檔中變更這些設定,您可能需要執行全新組建,以反映新的設定 (刪除 objbin 目錄並重建)。

如需在執行階段設定編譯的詳細資訊,請參閱適用於編譯的執行階段組態選項

ReadyToRun 映像

您可以透過將應用程式組件編譯為 ReadyToRun (R2R) 格式,來改善 .NET Core 應用程式的啟動時間。 R2R 是一種預先(AOT) 編譯。

R2R 二進位檔會透過減少 Just-In-Time (JIT) 編譯器在應用程式載入時所需執行的工作量,來改善啟動效能。 二進位檔包含的機器碼,與 JIT 所會產生的內容類似。 但是,R2R 二進位檔大小較大,因為它們會同時包含中繼語言 (IL) 程式碼 (在某些案例下仍需要使用),以及相同程式碼的原生版本。 R2R 只有在您發佈以特定執行階段環境 (RID) (例如 Linux x64 或 Windows x64) 為目標的獨立式應用程式時才可供使用。

若要將您的專案編譯為 ReadyToRun,請執行下列操作:

  1. <PublishReadyToRun> 設定新增至專案:

    <PropertyGroup>
      <PublishReadyToRun>true</PublishReadyToRun>
    </PropertyGroup>
    
  2. 發佈自封式應用程式。 例如,此命令會針對 64 位元版本的 Windows 建立自封式應用程式:

    dotnet publish -c Release -r win-x64 --self-contained
    

跨平台/架構限制

ReadyToRun 編譯器目前不支援跨目標。 您必須在指定的目標上進行編譯。 例如,如果您想要適用於 Windows x64 的 R2R 映像,便需要在該環境上執行發佈命令。

鎖定多重目標的例外狀況:

  • Windows x64 可以用來編譯 Windows Arm32、Arm64 及 x86 映像。
  • Windows x86 可以用來編譯 Windows Arm32 映像。
  • Linux x64 可以用來編譯 Linux Arm32 和 Arm64 映像。

如需詳細資訊,請參閱準備好執行

執行階段/SDK

主要版本執行階段向前復原

.NET Core 3.0 引進選擇性功能,可讓您的應用程式向前復原到 .NET Core 最新主要版本。 此外,也已新增設定來控制如何將向前復原套用至您的應用程式。 這可透過下列方式進行設定:

  • 專案檔屬性:RollForward
  • 執行階段組態檔屬性:rollForward
  • 環境變數:DOTNET_ROLL_FORWARD
  • 命令列引數:--roll-forward

必須指定下列其中一個值。 若省略設定,Minor 會是預設值。

  • LatestPatch
    向前復原到最高的修補程式版本。 這會停用次要版本向前復原。
  • Minor
    如果缺少要求的次要版本,則會向前復原到最低次要版本中次高的版本。 如果要求的次要版本存在,則會使用 LatestPatch 原則。
  • Major
    如果缺少要求的主要版本,則會向前復原到最低主要版本中次高的版本,以及最低的次要版本。 如果要求的主要版本存在,則會使用 Minor 原則。
  • LatestMinor
    向前復原到最高的次要版本,即使要求的次要版本存在也一樣。 適用於裝載案例的元件。
  • LatestMajor
    向前復原到最高主要版本和最高次要版本,即使要求的主要版本存在也一樣。 適用於裝載案例的元件。
  • 停用
    不會向前復原。 只會繫結至指定的版本。 此原則不建議一般用途,因為它會停用向前復原到最新修補程式的功能。 只有測試時才建議使用這個值。

除了 Disable 設定,所有設定都會使用最高可用的修補程式版本。

根據預設,如果要求的版本 (正如對於應用程式在 .runtimeconfig.json 中所指定) 是發行版本,則只會對於向前復原考慮發行版本。 系統會忽略任何發行前版本。 如果沒有相符的發行版本,則會考慮發行前版本。 您可以設定 DOTNET_ROLL_FORWARD_TO_PRERELEASE=1 變更這種行為,在此情況下,一律會考慮所有版本。

組建複本相依性

dotnet build 命令現在會從 NuGet 快取將您應用程式的 NuGet 相依性複製到組建輸出資料夾。 先前,只有在進行 dotnet publish 的過程中,才會複製相依性。

有些作業 (例如修剪和 Razor 頁面發佈) 仍然需要發佈。

本機工具

.NET Core 3.0 引進本機工具。 本機工具與全域工具類似,但與磁碟上的某個特定位置立建立關聯。 本機工具並非全域可用,而是以 NuGet 套件形式散發。

本機工具會倚賴您目前目錄中名為 dotnet-tools.json 的資訊清單檔。 此資訊清單檔定義可在該資料夾和以下資料夾提供的工具。 您可以隨程式碼散發資訊清單檔,確保使用您程式碼的任何人都能進行還原並使用相同工具。

不論是全域工具還是區域工具,都需要一個相容的執行階段版本。 NuGet.org 上目前許多工具都以 .NET Core 執行階段 2.1 為目標。 若要在全域或本機安裝這些工具,您仍然需要安裝 .NET Core 2.1 執行階段

新的 global.json 選項

global.json 檔案有新的選項,可讓您在嘗試定義使用哪個 .NET Core SDK 版本時提供更多彈性。 新的選項如下:

  • allowPrerelease:指出在選取要使用的 SDK 版本時,SDK 解析器是否應考慮發行前版本。
  • rollForward:指出選取 SDK 版本時要使用的向前復原原則,可能是當特定 SDK 版本遺失時做為後援,或是做為使用較高版本的指示詞。

如需變更的詳細資訊,包括預設值、支援的值和新比對規則,請參閱 global.json 概觀

較小的記憶體回收堆積大小

已減少記憶體回收行程的預設堆積大小,而導致 .NET Core 使用較少的記憶體。 這項變更較符合使用新式處理器快取大小的層代 0 配置預算。

記憶體回收大型頁面支援

大型頁面 (Large Page,在 Linux 上又稱為 Huge Page) 是一項功能,其中作業系統能夠建立大於原生頁面大小 (通常為 4K) 的記憶體區域,以提升要求這些大型頁面的應用程式效能。

記憶體回收行程現在可以設定 GCLargePages 設定作為選擇性功能,來選擇在 Windows 上配置大型頁面。

Windows 桌面與 COM

.NET Core SDK Windows Installer

Windows 的 MSI 安裝程式從 .NET Core 3.0 開始即已變更。 SDK 安裝程式現在會就地升級 SDK 功能帶版本。 功能帶是在版本號碼「修補程式」部分以「一百」為單位的群組中定義。 例如,3.0.1013.0.201 便是位於兩個不同功能帶中的版本,而 3.0.1013.0.199 則位於相同的功能帶。 此外,安裝 .NET Core SDK 3.0.101 時,.NET Core SDK 3.0.100 便會從電腦移除 (若存在的話)。 在相同電腦上安裝 .NET Core SDK 3.0.200 時,不會移除 .NET Core SDK 3.0.101

如需版本設定的詳細資訊,請參閱 .NET Core 版本設定概觀

Windows 桌面

.NET Core 3.0 支援使用 Windows Presentation Foundation (WPF) 和 Windows Forms 的 Windows 傳統型應用程式。 這些架構也支援透過 XAML 島使用來自 Windows UI XAML 程式庫 (WinUI) 的新式控制項和 Fluent 樣式。

「Windows 傳統型」元件是 Windows .NET Core 3.0 SDK 的一部分。

您可以使用下列 dotnet 命令來建立新的 WPF 或 Windows Forms 應用程式:

dotnet new wpf
dotnet new winforms

Visual Studio 2019 會新增 [新增專案] 範本,供 .NET Core 3.0 Windows Forms 和 WPF 使用。

如需如何移植現有 .NET Framework 應用程式的詳細資訊,請參閱移植 WPF 專案移植 Windows Forms 專案

WinForms 高 DPI

.NET Core Windows Forms 應用程式可以使用 Application.SetHighDpiMode(HighDpiMode) 設定高 DPI 模式。 除非已透過其他方法 (例如在 Application.Run 前面加上 App.Manifest 或 P/Invoke) 進行設定,否則 SetHighDpiMode 方法可以設定對應的高 DPI 模式。

可能的 highDpiMode 值 (如 System.Windows.Forms.HighDpiMode 列舉所示) 為:

  • DpiUnaware
  • SystemAware
  • PerMonitor
  • PerMonitorV2
  • DpiUnawareGdiScaled

如需高 DPI 模式的詳細資訊,請參閱 Windows 上的高 DPI 傳統型應用程式開發

建立 COM 元件

您現在可以在 Windows 上建立 COM 可呼叫受控元件。 此功能對於搭配 COM 增益集模型使用 .NET Core 很重要,也提供 .NET Framework 同位。

不同於 .NET Framework (其中使用 mscoree.dll 作為 COM 伺服器),.NET Core 會在您建置 COM 元件時,將原生啟動器 DLL 新增至 bin 目錄。

如需如何建立及取用 COM 元件的範例,請參閱 COM Demo (COM 示範)。

Windows 原生 Interop

Windows 提供豐富的原生 API,其採用的形式為一般 C API、COM 和 WinRT。 除了 .NET Core 3.0 支援 P/Invoke 之外,.NET Core 3.0 還新增 CoCreate COM APIActivate WinRT API 的功能。 如需程式碼範例,請參閱 Excel Demo (Excel 示範)。

MSIX 部署

MSIX 是新的 Windows 應用程式套件格式。 它可以用來將 .NET Core 3.0 桌面應用程式部署至 Windows 10。

Visual Studio 2019 中提供的 Windows 應用程式套件專案 \(機器翻譯\) 可讓您利用獨立式 .NET Core 應用程式建立 MSIX 套件。

.NET Core 專案檔必須指定在 <RuntimeIdentifiers> 屬性中支援的執行階段:

<RuntimeIdentifiers>win-x86;win-x64</RuntimeIdentifiers>

Linux 改善

適用於 Linux 的 SerialPort

.NET Core 3.0 提供 Linux 上 System.IO.Ports.SerialPort 的基本支援。

先前,.NET Core 僅支援在 Windows 上使用 SerialPort

如需 Linux 上序列埠有限支援的詳細資訊,請參閱 GitHub 問題 #33146

Docker 和 cgroup 記憶體限制

在 Linux 上執行 .NET Core 3.0 和 Docker 搭配 cgroup 記憶體限制的效果最佳。 使用記憶體限制 (例如使用 docker run -m) 執行 Docker 容器會變更 .NET Core 的運作方式。

  • 預設記憶體回收行程 (GC) 堆積大小:上限為 20 MB,或容器上 75% 的記憶體限制。
  • 可將明確大小設定為 cgroup 限制的絕對數目或百分比。
  • 每個 GC 堆積的保留區段大小下限為 16 MB。 此大小可減少電腦上所建立的堆積數目。

Raspberry Pi 的 GPIO 支援

兩個套件已發佈至您可以用於 GPIO 程式設計的 NuGet:

GPIO 套件包含 GPIOSPII2CPWM 裝置的 API。 IoT 繫結套件包含裝置繫結。 如需詳細資訊,請參閱裝置 GitHub 存放庫

Arm64 Linux 支援

.NET Core 3.0 新增 Arm64 for Linux 的支援。 Arm64 的主要使用案例目前是搭配 IoT 案例。 如需詳細資訊,請參閱 .NET Core Arm64 Status (.NET Core Arm64 狀態)。

Arm64 上適用於 .NET Core 的 Docker 映像可供 Alpine、Debian 和 Ubuntu 使用。

注意

macOS Arm64 (或「Apple Silicon」) 和 Windows Arm64 作業系統的支援稍後會在 .NET 6 中新增。

安全性

Linux 上的 TLS 1.3 和 OpenSSL 1.1.1

.NET Core 現在會利用 OpenSSL 1.1.1 中的 TLS 1.3 支援 (當在指定的環境中有提供時)。 透過 TLS 1.3:

  • 因為用戶端與伺服器之間所需的來回行程次數減少,所以改善了連線時間。
  • 因為移除各種已淘汰和不安全的密碼編譯演算法,所以提升了安全性。

.NET Core 3.0 在 Linux 系統上使用 OpenSSL 1.1.1OpenSSL 1.1.0OpenSSL 1.0.2 (若可供使用)。 當 OpenSSL 1.1.1 可供使用時,System.Net.Security.SslStreamSystem.Net.Http.HttpClient 類型就會使用 TLS 1.3 (假設用戶端和伺服器都支援 TLS 1.3)。

下列 C# 8.0 範例示範連線至 https://www.cloudflare.com 之 Ubuntu 18.10 上的 .NET Core 3.0:

using System;
using System.Net.Security;
using System.Net.Sockets;
using System.Threading.Tasks;

namespace whats_new
{
    public static class TLS
    {
        public static async Task ConnectCloudFlare()
        {
            var targetHost = "www.cloudflare.com";

            using TcpClient tcpClient = new TcpClient();

            await tcpClient.ConnectAsync(targetHost, 443);

            using SslStream sslStream = new SslStream(tcpClient.GetStream());

            await sslStream.AuthenticateAsClientAsync(targetHost);
            await Console.Out.WriteLineAsync($"Connected to {targetHost} with {sslStream.SslProtocol}");
        }
    }
}

密碼編譯加密方式

.NET Core 3.0 新增對 AES-GCMAES-CCM 加密方式的支援,分別透過 System.Security.Cryptography.AesGcmSystem.Security.Cryptography.AesCcm 來實作。 這些演算法都是搭配關聯資料的驗證加密 (AEAD) 演算法

下列程式碼示範如何使用 AesGcm 加密方式將隨機資料加密和解密。

using System;
using System.Linq;
using System.Security.Cryptography;

namespace whats_new
{
    public static class Cipher
    {
        public static void Run()
        {
            // key should be: pre-known, derived, or transported via another channel, such as RSA encryption
            byte[] key = new byte[16];
            RandomNumberGenerator.Fill(key);

            byte[] nonce = new byte[12];
            RandomNumberGenerator.Fill(nonce);

            // normally this would be your data
            byte[] dataToEncrypt = new byte[1234];
            byte[] associatedData = new byte[333];
            RandomNumberGenerator.Fill(dataToEncrypt);
            RandomNumberGenerator.Fill(associatedData);

            // these will be filled during the encryption
            byte[] tag = new byte[16];
            byte[] ciphertext = new byte[dataToEncrypt.Length];

            using (AesGcm aesGcm = new AesGcm(key))
            {
                aesGcm.Encrypt(nonce, dataToEncrypt, ciphertext, tag, associatedData);
            }

            // tag, nonce, ciphertext, associatedData should be sent to the other part

            byte[] decryptedData = new byte[ciphertext.Length];

            using (AesGcm aesGcm = new AesGcm(key))
            {
                aesGcm.Decrypt(nonce, ciphertext, tag, decryptedData, associatedData);
            }

            // do something with the data
            // this should always print that data is the same
            Console.WriteLine($"AES-GCM: Decrypted data is {(dataToEncrypt.SequenceEqual(decryptedData) ? "the same as" : "different than")} original data.");
        }
    }
}

密碼編譯金鑰匯入/匯出

.NET Core 3.0 支援從標準格式匯入及匯出非對稱式公開金鑰與私密金鑰。 您無須使用 X.509 憑證。

所有金鑰類型 (例如 RSADSAECDsaECDiffieHellman) 都支援下列格式:

  • 公開金鑰

    • X.509 SubjectPublicKeyInfo
  • 私密金鑰

    • PKCS#8 PrivateKeyInfo
    • PKCS#8 EncryptedPrivateKeyInfo

RSA 金鑰也支援:

  • 公開金鑰

    • PKCS#1 RSAPublicKey
  • 私密金鑰

    • PKCS#1 RSAPrivateKey

匯出方法會產生 DER 編碼的二進位資料,而匯入方法也是如此。 如果金鑰是以適合文字的 PEM 格式儲存的,呼叫端在呼叫匯入方法之前,就必須先對內容進行 Base64 解碼。

using System;
using System.Security.Cryptography;

namespace whats_new
{
    public static class RSATest
    {
        public static void Run(string keyFile)
        {
            using var rsa = RSA.Create();

            byte[] keyBytes = System.IO.File.ReadAllBytes(keyFile);
            rsa.ImportRSAPrivateKey(keyBytes, out int bytesRead);

            Console.WriteLine($"Read {bytesRead} bytes, {keyBytes.Length - bytesRead} extra byte(s) in file.");
            RSAParameters rsaParameters = rsa.ExportParameters(true);
            Console.WriteLine(BitConverter.ToString(rsaParameters.D));
        }
    }
}

PKCS#8 檔案可以使用 System.Security.Cryptography.Pkcs.Pkcs8PrivateKeyInfo 來檢查,而 PFX/PKCS#12 檔案可以使用 System.Security.Cryptography.Pkcs.Pkcs12Info 來檢查。 PFX/PKCS#12 檔案可以使用 System.Security.Cryptography.Pkcs.Pkcs12Builder 來操作。

.NET Core 3.0 API 變更

範圍和索引

新的 System.Index 類型可用於編製索引。 您可以從會從開頭算起的 int 或使用會從結尾算起的前置詞 ^ 運算子 (C#),來建立一個索引:

Index i1 = 3;  // number 3 from beginning
Index i2 = ^4; // number 4 from end
int[] a = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Console.WriteLine($"{a[i1]}, {a[i2]}"); // "3, 6"

此外,還有 System.Range 類型,此類型由兩個 Index 值所組成 (一個代表開頭,一個代表結尾),並可用 x..y 範圍運算式 (C#) 來撰寫。 您可以接著使用 Range 來編製索引以產生配量:

var slice = a[i1..i2]; // { 3, 4, 5 }

如需詳細資訊,請參閱範圍和索引教學課程

非同步資料流

IAsyncEnumerable<T> 類型是 IEnumerable<T> 的新非同步版本。 此語言可讓您透過 IAsyncEnumerable<T> 執行 await foreach 以取用其元素,然後對它們使用 yield return 以產生元素。

下列範例同時示範如何產生和取用非同步資料流。 foreach 是非同步陳述式,其本身會使用 yield return 來為呼叫端產生非同步資料流。 此模式 (使用 yield return) 是針對產生非同步資料流建議採用的模型。

async IAsyncEnumerable<int> GetBigResultsAsync()
{
    await foreach (var result in GetResultsAsync())
    {
        if (result > 20) yield return result;
    }
}

除了能夠執行 await foreach 之外,您也可以建立非同步迭代器,例如建立一個會傳回 IAsyncEnumerable/IAsyncEnumerator 以供您在其中執行 awaityield 的迭代器。 針對需要處置的物件,您可以使用各種 BCL 類型 (例如 StreamTimer) 所實作的 IAsyncDisposable

如需詳細資訊,請參閱非同步資料流教學課程

IEEE 浮點數

正在更新浮點 API,以遵守 IEEE 754-2008 修訂。 這些變更的目標是公開所有的必要作業,並確定它們在行為上符合 IEEE 規格。如需浮點增強功能的詳細資訊,請參閱 Floating-Point Parsing and Formatting improvements in .NET Core 3.0 (.NET Core 3.0 中的浮點剖析和格式化增強功能) 部落格文章。

剖析與格式化修正包括:

  • 正確地剖析並捨入任意長度的輸入。
  • 正確地剖析並格式化負零。
  • 正確地剖析 InfinityNaN,方法為執行不區分大小寫的檢查,並允許適當時在前面選擇性加上 +

新的 System.Math API 包括:

  • BitIncrement(Double)BitDecrement(Double)
    對應至 nextUpnextDown IEEE 作業。 它們會傳回最小浮點數,比較大於或小於輸入 (分別)。 例如,Math.BitIncrement(0.0) 會傳回 double.Epsilon

  • MaxMagnitude(Double, Double)MinMagnitude(Double, Double)
    對應至 maxNumMagminNumMagIEEE 作業,它們傳回的值大於或小於兩個輸入的範圍 (分別)。 例如,Math.MaxMagnitude(2.0, -3.0) 會傳回 -3.0

  • ILogB(Double)
    對應至傳回整數值的 logB IEEE 作業,它會傳回輸入參數的對數,以整數 2 為底數。 此方法實際上與 floor(log2(x)) 相同,但完成時發生最少捨入錯誤。

  • ScaleB(Double, Int32)
    對應至採用整數值的 scaleB IEEE 作業,它會有效傳回 x * pow(2, n),但完成時發生最少捨入錯誤。

  • Log2(Double)
    對應至 log2 IEEE 作業,它會傳回 2 為底數的對數。 它會將捨入錯誤減至最少。

  • FusedMultiplyAdd(Double, Double, Double)
    對應至 fma IEEE 作業,它會執行融合的乘積和。 亦即,它會將 (x * y) + z 當作單一作業來執行,藉此將捨入錯誤減至最少。 範例是 FusedMultiplyAdd(1e308, 2.0, -1e308),這會傳回 1e308。 一般 (1e308 * 2.0) - 1e308 會傳回 double.PositiveInfinity

  • CopySign(Double, Double)
    對應至 copySign IEEE 作業,它會傳回 x 的值,但具有 y 的符號。

.NET 平台相依內建

已新增 API,允許存取特定效能導向的 CPU 指令,例如 SIMD位元操作指令集合。 這些指令可協助您在某些情況 (例如有效率地平行處理資料) 下大幅提升效能。

.NET 程式庫 (如果適用) 已開始使用這些指令來提升效能。

如需詳細資訊,請參閱 .NET Platform Dependent Intrinsics (.NET 平台相依內建)。

改善的 .NET Core 版本 API

從 .NET Core 3.0 開始,.NET Core 所提供版本 API 現在會傳回您預期的資訊。 例如:

System.Console.WriteLine($"Environment.Version: {System.Environment.Version}");

// Old result
//   Environment.Version: 4.0.30319.42000
//
// New result
//   Environment.Version: 3.0.0
System.Console.WriteLine($"RuntimeInformation.FrameworkDescription: {System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription}");

// Old result
//   RuntimeInformation.FrameworkDescription: .NET Core 4.6.27415.71
//
// New result (notice the value includes any preview release information)
//   RuntimeInformation.FrameworkDescription: .NET Core 3.0.0-preview4-27615-11

警告

重大變更。 這是技術上的重大變更,因為版本設定配置已變更。

快速的內建 JSON 支援

.NET 使用者大幅倚賴 Newtonsoft.Json 及其他熱門的 JSON 程式庫 (這些仍持續是絕佳的選擇)。 Newtonsoft.Json 使用 .NET 字串作為其基底資料類型,實際上就是 UTF-16。

新的內建 JSON 支援達到高效能和低配置,並且可搭配 UTF-8 編碼的 JSON 文字使用。 如需 System.Text.Json 命名空間和型別的詳細資訊,請參閱下列文章:

HTTP/2 支援

System.Net.Http.HttpClient 類型支援 HTTP/2 通訊協定。 如果啟用 HTTP/2,則會透過 TLS/ALPN 交涉 HTTP 通訊協定版本,並會在伺服器選擇使用它時使用 HTTP/2。

預設通訊協定會保持為 HTTP/1.1,但 HTTP/2 可以兩種不同的方式啟用。 首先,您可以設定 HTTP 要求訊息來使用 HTTP/2:

var client = new HttpClient() { BaseAddress = new Uri("https://localhost:5001") };

// HTTP/1.1 request
using (var response = await client.GetAsync("/"))
    Console.WriteLine(response.Content);

// HTTP/2 request
using (var request = new HttpRequestMessage(HttpMethod.Get, "/") { Version = new Version(2, 0) })
using (var response = await client.SendAsync(request))
    Console.WriteLine(response.Content);

再來,您可以變更 HttpClient 來預設使用 HTTP/2:

var client = new HttpClient()
{
    BaseAddress = new Uri("https://localhost:5001"),
    DefaultRequestVersion = new Version(2, 0)
};

// HTTP/2 is default
using (var response = await client.GetAsync("/"))
    Console.WriteLine(response.Content);

當您在開發應用程式時,經常會想要使用未加密的連線。 如果您知道目標端點會使用 HTTP/2,便可以針對 HTTP/2 開啟未加密的連線。 若要開啟它,您可以將 DOTNET_SYSTEM_NET_HTTP_SOCKETSHTTPHANDLER_HTTP2UNENCRYPTEDSUPPORT 環境變數設定為 1,或是在應用程式內容中啟用它:

AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);

下一步