官宣 .NET RC 2

MicrosoftReactor發表於2021-11-08

我們很高興釋出 .NET 6 RC(Release Candidate) 2。它是生產環境中支援的兩個"go live"候選版本中的第二個。 在過去的幾個月裡,團隊一直專注於質量的改進。這個版本中有很多的新特性,但在接近尾聲時我們才會把他們完全整合在一起。該團隊目前正在驗證端到端工作流,以找到設計意圖和技術現實尚未完全匹配的地方。這導致團隊裡的維護人員不得不修改bug來達到這個目的。

我們從使用者那裡聽說,將生產站點升級到.NET 6是既"無聊"(非事件)又"令人興奮"(顯著的效能改進)的。不出意外,我們相信RC2將繼續保持這種趨勢。

您可以下載適用於 Linux、macOS 和 Windows 的 .NET 6 Release Candidate2

請參閱 .NET MAUIASP.NET Core帖子,瞭解有關客戶端和 Web 應用程式場景新增功能的更多詳細資訊。

.NET 大會是一個免費的,為期三天的虛擬開發者活動,用來慶祝.NET的主要版本。 今年,.NET 6 將於 11 月 9 日至 11 日在 .NET 大會上釋出。我們期待您可以記下日期準時收聽。Visual Studio 2022 預覽版 5 也在今天釋出,他們還宣佈將於 11 月 8 日舉行釋出活動。您可以在 Visual Studio 部落格上閱讀所有相關內容。

我們正處於支援生產新版本的週期的這一有趣部分中。我們真誠地鼓勵它。如果你需要有關如何處理的指導,可以通過dotnet@microsoft.com聯絡我們。許多企業已經開始接觸,有些已經開始生產。我們還幫助 Microsoft 團隊在 RC 版本上執行。一些 Microsoft 團隊已經在 RC1 上投入生產,我們期待在 RC2 上有更多幫助。這包括 .NET 網站

.NET 6 RC2已經經過測試,並得到了Visual Studio 2022 Preview 5的支援,也在今天釋出。Visual Studio 2022將支援.NET 6, 而Visual Studio 2019不支援。同樣,MSBuild 17.x將支援它,而16.x 不支援。如果你想使用.NET 6,你需要升級到Visual Studio 2022。

支援Mac版本的Visual Studio 2022目前與.NET 6 RC2不相容。我們正在解決這個問題。

檢視新的對話帖子,就最新的 .NET 功能進行工程師對工程師的深入討論。

.NET 6 RC1 帖子側重於基礎功能,其中許多功能要到 .NET 7 才能完全實現。本文重點介紹 C# 10 和模板的相關改進。它還包括 macOS 和 Windows Arm64 的更新(包括重大更改)。讓我們來看看。

C#10

C# 10是 .NET 6 版本的重要組成部分。在很大程度上,C# 10是對現有概念和功能(如記錄和模式)的進一步演變。它還包括一些特性——全域性使用和檔案作用域的名稱空間——可以幫助您簡化程式碼並編寫更少的樣板檔案。這些具體的改進是本文後面討論的模板更改的基礎。您可以在.NET 6的示例中看到本節中使用的示例。我將在.NET 6的最後一個帖子中新增更多的例子。

Record structs
C# 10增加了對Record structs的支援。這個新特性類似於C# 9(基於類的)記錄,但有一些主要的區別。在大多數情況下,新增Record structs是為了完整性,這樣結構就可以享受與類相同的記錄優勢。然而,該團隊並沒有簡單地結構化記錄,而是決定將結構記錄與ValueTuple保持一致,就像類記錄匹配一致。由於這種設計方法,Record structs的屬性在預設情況下是可變的,而Record類屬性是不可變的。但是,您可以宣告一個只讀的Record structs,它是不可變的,並匹配記錄類語義。

在較高的層次上,Record structs不會取代Record類,我們也不鼓勵將Record類遷移到Record structs。使用類vs結構的指導同樣適用於Record類和Record structs。換句話說,在選擇使用Record之前,應該在類和結構之間做出選擇。

讓我們看看Record structs與Record類有何不同

Battery battery = new("CR2032", 0.235, 100);
WriteLine(battery);
while (battery.RemainingCapacityPercentage > 0)
{
    battery.RemainingCapacityPercentage--;
}
WriteLine(battery);
public record struct Battery(string Model, double TotalCapacityAmpHours, int RemainingCapacityPercentage);

這個Record structs的示例產生如下結果

Battery { Model = CR2032, TotalCapacityAmpHours = 0.235, RemainingCapacityPercentage = 100 }
Battery { Model = CR2032, TotalCapacityAmpHours = 0.235, RemainingCapacityPercentage = 0 }

如前所述,最明顯的區別是記錄結構屬性在預設情況下是可變的。這是除了結構體和記錄結構體語法之外的主要區別。我還用一個只讀記錄結構重寫了這個示例,如下所示。

Battery battery = new("CR2032", 0.235, 100);
WriteLine(battery);
while (battery.RemainingCapacityPercentage > 0)
{
    Battery updatedBattery = battery with {RemainingCapacityPercentage = battery.RemainingCapacityPercentage - 1};
    battery = updatedBattery;
}
WriteLine(battery);
public readonly record struct Battery(string Model, double TotalCapacityAmpHours, int RemainingCapacityPercentage);

您將看到它幾乎與我為C# 9釋出的(類)Record示例相同。

讓我們回顧一下C# 9的記錄。它們提供了一種簡潔的語法為定義類似結構的面向資料的類。他們偏向於不變性,同時提供簡潔的語法——帶有表示式——為了不可變友好的複製。 人們可能會驚訝於我們開始使用類來實現類似結構的功能。大多數時候,開發人員使用類而不是結構,這是由於引用傳遞而不是值語義。 在大多數情況下,類是最好的選擇,而且易於使用。

結構記錄與類記錄非常相似:

  • 它們使用相同的語法(除了定義中的struct或class)。
  • 它們允許自定義成員定義(在C#10中新增)以在(預設情況下)屬性成員上使用欄位。
  • 它們允許使用init或可變屬性定製成員行為。
  • 它們支援表示式。事實上,從C# 10開始,所有的結構型別都支援表示式。

結構記錄不同於類記錄:

  • Record structs可以用Record structs或只讀Record structs來定義。
  • 記錄類是用記錄或記錄類定義的。
  • 預設情況下,Record structs屬性是可變的(get/set)。
  • 預設情況下,記錄類屬性是不可變的(get/init)。

Record structs和Record類之間的非對稱(不)可變性行為可能會讓一些讀者感到驚訝,甚至厭惡。我會試著解釋設計背後的想法。由於通過值傳遞語義,結構從不變性中獲得的好處幾乎不如類。例如,如果結構體是字典中的鍵,則該(結構體的副本)鍵是不可變的,只能將通過相等執行查詢。與此同時,設計團隊認為ValueTuple可以被視為一個匿名的記錄結構,而Record structs可以被視為ValueTuple的衍生。只有當記錄結構包含可變性和支援欄位時,這才有效,這正是團隊決定要做的。另外,包含可變性反映了結構和類的不同。

如果您更喜歡記錄結構的不可變行為,您可以通過新增 readonly 關鍵字來獲得它。

Looking at structs generally, key functionality is common:

  • 執行時提供的等同性檢查對所有結構都是相同的。
  • 所有的結構都可以和表示式一起用來建立非變異的副本,這是C# 10中的新功能。

Global usings

global using使您可以指定一個你想要在所有原始檔中可用的名稱空間,就像在每個原始檔中都宣告瞭它一樣。它也可以用於使用靜態和別名一起使用。該特性允許使用一組通用的using宣告,並擴充套件為不再需要的更多的using行。這與命名名稱空間最為相關,但可以用於任何名稱空間。

以下語法可用於各種使用形式:

  • global using System;
  • global using static System.Console;
  • global using E = System.Environment;

這些宣告只需要在編譯中宣告一次就可以了。有四種模式宣告global using。

  • 在 Program.cs 中,通過將根 using 語句升級為global using 來使它們對整個程式具有全域性性。
  • 在globaluses .cs檔案(或類似的名稱)中,集中管理所有的global using語句。
  • 在專案檔案中,使用下面的語法。
  • 在你的專案檔案中,使用語句(對於你的應用所依賴的MSBuild SDK)啟用預設平臺,語法如下。

下面的MSBuild語法可以在(使用與前面示例類似的方法)中代替.cs檔案。

  • < Using Include="System"/ >
  • < Using Include="System.Console" Static="True"/ >
  • < Using Include="System.Environment" Alias="E"/ >

您可以在 < PropertyGroup >中啟用由平臺定義的隱式 using 語句。

  • < ImplicitUsings > enable < /ImplicitUsings >

隱式使用不同的 MSBuild SDK。Microsoft.NET.Sdk定義了一個基本集,其他sdk定義附加集。

如果使用MSBuild功能,您可以在obj目錄中生成的檔案中看到有效的結果,如下所示。

PS C:\Users\rich\app> type .\app.csproj | findstr Using
    <ImplicitUsings>enable</ImplicitUsings>
    <Using Include="System.Console" Static="True"/>
    <Using Include="System.Environment" Alias="E"/>
PS C:\Users\rich\app> type .\obj\Debug\net6.0\app.GlobalUsings.g.cs
// <auto-generated/>
global using global::System;
global using global::System.Collections.Generic;
global using global::System.IO;
global using global::System.Linq;
global using global::System.NET.Http;
global using global::System.Threading;
global using global::System.Threading.Tasks;
global using E = global::System.Environment;
global using static global::System.Console;

您可以看到,Microsoft.NET.Sdk在. globalusings .g.cs檔案中新增了幾個global using語句。請注意,全域性的::操作符不是必需的,為了理解生成的語法,可以放心地忽略它。

檔案與名稱空間宣告

檔案作用域名稱空間的宣告是C# 10的另一個特性,旨在減少縮排和行數。

此功能的語法如下:
namespaceFoo;

它是傳統三行語法的替代方案:
namespaceFoo
{
}

三行語法可以巢狀。單行語法不支援巢狀。每個檔案只能有一個檔案作用域的宣告。它必須在檔案中定義的所有型別之前,很像三行語法。

名稱空間與頂級語句不相容。頂級語句存在於頂級名稱空間中。這還意味著,如果您向Program類新增額外的方法,使用partial類語法,則partial Program類也需要位於頂級名稱空間中。

這個特性非常類似於新增到C# 8中的單行using宣告

Const 和內插字串

現在您可以將內插字串分配給 const 變數。插值字串使用和讀取都很直觀,在任何地方都可用。現在,它們可以與 const 一起使用,前提是佔位符值也是常量。

以下示例演示了一個可能使用的例子:

const string Bar = "Bar";
const string DoubleBar = $"{Bar}_{Bar}";
WriteLine(DoubleBar);

字串插值進行了許多其他改進,在 C# 10 和 .NET 6 中的字串插值中進行了描述。

擴充套件屬性模式

你現在可以在屬性模式中引用巢狀屬性或欄位。例如,下面的模式現在是合法的:

{Prop1.Prop2: pattern }

以前,你需要使用更詳細的形式:

{Prop1:{Prop2: pattern }}

您可以在下面的示例中看到使用這種更緊湊的形式,例如使用Reading.PM25。

List<Status> statuses = new()
{
    new(Category.Normal, new(20, false, 20)),
    new(Category.Warning, new(20, false, 60)),
    new(Category.Danger, new(20, true, 60)),
    new(Category.Danger, new(100, false, 20))
};
foreach (Status status in statuses)
{
    string message = status switch
    {
        {Category: Category.Normal} => "Let the good times roll",
        {Category: Category.Warning, Reading.PM25: >50 and <100} => "Check the air filters",
        {Reading.PM25: >200 } => "There must be a fire somewhere. Don't go outside.",
        {Reading.SmokeDetected: true } => "We have a fire!",
        {Category: Category.Danger} => "Something is badly wrong",
        _ => "Unknown status"
    };
    Console.WriteLine(message);
}
record struct Reading(int Temperature, bool SmokeDetected, int PM25);
record struct Status(Category Category, Reading Reading);
enum Category
{
    Normal,
    Warning,
    Danger
}

.NET SDK:現代化的 C# 專案模板

我們在Preview 7中更新了.NET SDK模板,使用了最新的C#特性和模式。對這些更改有重要反饋,部分原因是構建開始失敗。作為初始模板更新的一部分,我們預設為.NET6(NET 6.0)專案(包括從.NET 5更新到.NET 6的應用程式)啟用了隱式使用(又名opt-out)。那已經改變了。我們已經更新了SDK,所以所有的新功能都是可選的。對這個變化(在RC1中做出的)的響應是積極的。

也有反饋說,有些人不喜歡新的簡化的Program.cs檔案,其中有頂級語句。我們對頂級語句進行了改進,並繼續將其用於模板。我們希望大多數喜歡傳統方法的開發人員可以直接自己新增額外的方式。

新模板中使用了以下語言特性:

  • 非同步Main
  • 頂級語句
  • Target-typed新表示式
  • global using指令
  • 檔案作用域名稱空間
  • 可空引用型別

我們構建了所有這些功能,因為我們認為它們比之前的替代方案更好。模板是引導新開發人員和新應用程式使用最佳模式的最簡單和最好的方法。C#設計團隊堅信使用更少的行數、更少的字元來指定給定的概念或操作,並減少不必要的重複。這就是大多數這些新功能所支援的。Nullable 的不同之處在於它產生更可靠的程式碼。每個使用nullable的應用程式或庫都不太可能在生產中崩潰。軟體太複雜了,人類無法像編譯器那樣看到錯誤。

這些功能的一個共同主題是,當您在程式碼編輯器中檢視程式碼時,它們會減少干擾並增加提示。 現在,更加重要的方面會彈出。例如,如果您在給定的檔案中看到using語句,那麼它是隱式集之外需要的特殊語句。你應該能夠複製/貼上程式碼從一個檔案到另一個不需要CTRL-.型別以新增所需的名稱空間(至少沒有那麼多)。如果您看到可空的警告或錯誤,您就知道您的程式碼可能在某些方面是不正確的。去除縮排還有好處。更多的程式碼將在編輯器的前十幾個列中可見,而不是僅僅用空格字元填充這些列。人們可以把這些特徵看作是在向大腦傳遞資訊的過程中,向眼睛傳遞更高密度的特異性和意義。

控制檯模板

讓我們從控制檯模板開始。這是非常小的。

Program.cs:

// 檢視 https://aka.ms/new-console-template 得到更多資訊
Console.WriteLine(&quot;Hello, World!&quot;);

Project 檔案:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
</Project>

儘管控制檯模板比它的.NET 5對應的模板要小得多,但在功能上並沒有減少。您還可以看到ImplicitUsings現在是一個可選擇的特性,並且在模板中啟用了它。

Web 模板

web模板也是很小的。

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();

webapi 模板更接近於典型的 ASP.NET Core 應用程式。 您會很快注意到 Program.cs 和 Startup.cs 之間的分離已被刪除。 不再需要 Startup.cs。

Program.cs:

var builder = WebApplication.CreateBuilder(args);
// 新增 services to the container.
builder.Services.AddControllers();
// 學習更多關於configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();

webapi 模板的專案檔案與控制檯類似。

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Swashbuckle.AspNetCore" Version="6.1.5" />
  </ItemGroup>
</Project>

您可以在本示例中看到檔案作用域名稱空間被使用,包括在WeatherForecast.cs中:

namespace webapi;
public class WeatherForecast
{
    public DateTime Date { get; set; }
    public int TemperatureC { get; set; }
    public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
    public string? Summary { get; set; }
}

目標型別 new 與 WeatherForecastController.cs 一起使用:

private static readonly string[] Summaries = new[]
{
    "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};

在mvc模板中,你可以看到可空註解和表示式體方法的使用。

namespace webmvc.Models;
public class ErrorViewModel
{
    public string? RequestId { get; set; }

    public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
}

Windows Forms 模板

Windows Forms模板也得到了更新。它包括了其他模板所涉及的大多數其他改進,儘管不是頂級語句。

namespace winforms;
static class Program
{
    /// <summary>
    ///  The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        ApplicationConfiguration.Initialize();
        Application.Run(new Form1());
    }    
}

您可以看到使用了單行名稱空間語句,而由於啟用了隱式使用,因此沒有任何平臺級 using 語句。

WPF 模板尚未作為版本的一部分進行更新。

隱式使用

現在我將向您展示這些特性的實際應用。讓我們從隱式用法開始。當啟用時,每個Sdk都會新增自己的一組隱式using語句

如前所述,Microsoft.NET.Sdk新增了幾個global using語句。

如果禁用該特性,您將看到應用程式不再編譯,因為不再宣告System名稱空間(在本例中) 。

PS C:Usersrichapp> type .app.csproj | findstr Implicit
    <ImplicitUsings>disable</ImplicitUsings>
PS C:Usersrichapp> dotnet build
Microsoft (R) Build Engine version 17.0.0-preview-21501-01+bbcce1dff for .NET
Copyright (C) Microsoft Corporation. All rights reserved.
  Determining projects to restore...
  All projects are up-to-date for restore.
  You are using a preview version of .NET. See: https://aka.ms/dotnet-core-preview
C:UsersrichappProgram.cs(2,1): error CS0103: The name 'Console' does not exist in the current context [C:Usersrichappapp.csproj]
Build FAILED.

另一種選擇是使用global using特性,它允許您只使用您想要的名稱空間,如下面的示例所示。

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>disable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
  <ItemGroup>
    <Using Include="System" />
  </ItemGroup>
</Project>

現在,構建程式碼。

PS C:Usersrichapp> type .app.csproj | findstr Using
    <ImplicitUsings>disable</ImplicitUsings>
  <Using Include="System" />
PS C:Usersrichapp> dotnet build
Microsoft (R) Build Engine version 17.0.0-preview-21501-01+bbcce1dff for .NET
Copyright (C) Microsoft Corporation. All rights reserved.
  Determining projects to restore...
  All projects are up-to-date for restore.
  You are using a preview version of .NET. See: https://aka.ms/dotnet-core-preview
  app -> C:UsersrichappbinDebugnet6.0app.dll
Build succeeded.
    0 Warning(s)
    0 Error(s)
Time Elapsed 00:00:00.80

這不是推薦的通用模式,但對於想要最大程度控制的人來說是一個不錯的選擇。在大多數情況下,我們預計開發人員將依賴於SDK提供的隱式使用,並從他們自己的程式碼或普遍使用的NuGet包中利用名稱空間的顯式global using。

可空性

我已經更新了Program.cs,用來演示可空的引用型別。應用程式呼叫List< T >方法,返回一個T?,在本例中是一個可空字串(string?)

List<string> greetings = new()
{
    "Nice day, eh?"
};
string? hello = greetings.Find(x => x.EndsWith("!"));
string greeting = hello ?? "Hello world!";
Console.WriteLine($"There are {greeting.Length} characters in "{greeting}"");

定義hello變數的行如果沒有定義為var, string?或者List< T >.Find返回null,那麼就不能夠被編譯。如果沒有啟用nullable特性,我可能會錯過這個問題,這將導致我的程式碼因NullReferenceException異常而崩潰。那就不好了。我在下一行使用?? 和空合併運算子。在大多數情況下,這兩行程式碼會合併為一行,如下面的程式碼所示。考慮到返回可空引用型別的API, 我將它們分開(在這個人為的示例中),以便您可以看到我使用的string?

string greeting = greetings.Find(x =\&gt; x.EndsWith(&quot;!&quot;))??&quot;Hello world!&quot;;

在本例中,我將所有內容合併到一行中。我現在可以將變數宣告為字串,因為null已經適應了??後面的字串。字串?在這種情況下,只有編譯器才能看到。

string[] args

現在,我將快速解決大多數人對頂級語句(包括args引數)提出的問題。args引數在頂級語句中仍然可用。只是不那麼明顯。下面是另一個演示如何使用它的程式。

string greeting = args.Length > 0 ? string.Join(" ", args) : "Hello World!";
WriteLine($"There are {greeting.Length} characters in "{greeting}" in this {nameof(Program)}.");

它產生以下結果。

PS C:\Users\rich\app> dotnet run
There are 12 characters in "Hello World!" in this Program.
PS C:\Users\rich\app> dotnet run Nice day, eh?
There are 13 characters in "Nice day, eh?" in this Program.

這個應用程式還演示了Program型別仍然是被定義的。Program.Main不是。

通過新增一個全域性靜態 using 到我的專案檔案,我從Program.cs中的Console.WriteLine中刪除了Console,如下所示。

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
  <ItemGroup>
    <Using Include="System.Console" Static="True"/>
  </ItemGroup>
</Project>

定義常規方法

我們已經聽到一些使用者的反饋,他們認為真正的方法優於區域性函式,特別是對於Program類。您可以使用任何一個帶有頂級語句的模型。

我保持程式不變,但將所有功能切換到 Program 類中的靜態方法,在部分類中定義。

Program.cs.
WriteLine(GetTheGreeting(args));
Program.Foo.cs.
public partial class Program
{
    public static string GetTheGreeting(string[] args)
    {
        string greeting = args.Length > 0 ? string.Join(" ", args) : "Hello World!";
        return $"There are {greeting.Length} characters in "{greeting}" in this {nameof(Program)}.";
    }
}

它產生與前面示例相同的結果。Program.Foo.cs檔名是任意的。事實上,Program.cs也是如此。你可以給這些檔案起任何你喜歡的名字。編譯器會找出他們。

如前所述,在使用頂級語句時,Program型別必須在頂級名稱空間中。

macOS and Windows Arm64 更新

我們除了有好訊息,也有一些突破性的變化要分享。支援macOS和Windows arm64的專案已經基本完成。在macOS和Windows團隊的幫助下,我們已經在這上面工作了一年多。起初,我們認為該專案只是為了在 macOS 上支援 Arm64,而 Rosetta 2 將涵蓋 x64。很簡單,就像ISAs,對吧?不完全是。隨著我們深入研究,我們發現x64 + Arm64共存是一個更大的任務,主要集中在CLI和安裝程式上,包括一些他們需要達成一致的地方。藉助 RC2,我們正在交付 .NET 的構建版本,以提供我們可以想象的最佳體驗。

我將快速總結一下我們在 macOS 和 Windows Arm64 machines的程式:

  • .NET 6 RC2 通過將 Arm64 和 x64 版本安裝到不同位置來實現 Arm64 + x64 共存。到目前為止,Arm64和x64構建相互覆蓋,which led to general sadness。
  • 您需要解除安裝所有 .NET 版本並從頭開始(在 macOS 和 Windows Arm64 機器上)以採用 .NET 6 RC2+。這包括 Arm64 和 x64、.NET 6 和 .NET 6 之前的版本。
  • .NET 6 之前的版本尚未準備好安裝。
  • CLI允許您使用Arm64 SDK進行Arm64和x64開發(假設您已經安裝了所需的Arm64和x64執行時)。反過來也是一樣。
  • 我們希望人們只使用Arm64 SDK,因為它會有更好的體驗(本機架構效能;只有一個SDK需要維護)。我們將繼續改進產品,使這一模式成為大多數開發者的簡單選擇。
  • 對於SDK,我們只在Arm64上支援.NET 6+。早期的SDK構建將在Arm64上被阻止
  • 對於執行時,我們將支援所有支援的版本,Arm64 和 x64。
  • .NET 6 RC2為Arm64(包括x64模擬)提供了大量的.NET 6最終體驗。
  • 我們希望更新.NET Core 3.1和.NET 5執行時,以與.NET 6 RTM保持一致(在時間上和技術上)。這還待定。
  • RC2的夜間構建目前是壞的,所以您需要再等幾周,直到我們真正釋出RC2來嘗試所有這些。
  • 針對Windows Arm64的.NET 5 SDK將會隨著.NET 6 RTM而提早退出支援。

我們也在考慮對dotnet test做一些突破性的改變,以統一我們用於架構目標的觀點:

該專案的很大一部分是通過 Arm64 SDK 啟用 x64 執行時。您可以在下圖中看到這一點。

如果你想了解更多細節,請檢視dotnet/sdk #21686

總結

C# 10基於C# 9的類似特性,在簡單性和可表達性方面提供了顯著的改進。過去,人們可以合理地嘲笑C#,因為僅僅編寫一行程式碼就需要這麼多的禮節和麵向物件概念的知識。那些日子已經過去了,模板反映了這一點。這些變化的部分動機是讓C#對新程式設計師和學校更有吸引力。這些簡化的改變從根本上改變了您開始學習和熟練使用C#所需要的東西。在新的預設形式下,它可以直接與其他類似地以單一檔案原始檔開始的語言相比較。

我們期待看到其他專案通過頂級語句、全域性使用、記錄和許多其他現代特性來簡化他們的新使用者體驗。有很多機會可以為開源專案和商業產品建立更簡單的學習旅程。

我們鼓勵您使用 .NET 6 RC2。我們相信您會發現它是一個可靠的版本。並將 全球.NET Conf 的日期會在11月9日,以便 .NET 6 釋出。

感謝您成為 .NET 開發人員。

相關文章