原文: [Introducing C# 10]
作者: Ken Bonny
?
本周早些時候(譯注:原文發表于5月1日),我關注了 Mads Torgersen 在 DotNet SouthWest 大會上的演講,他是微軟的 C# 語言的首席設計師,他概述了 C# 10 即將包含的很酷的一些新東西,讓我們來快速瀏覽一下,
小小的免責宣告,這些變化中的大部分已經基本完成,但是由于它仍在積極的開發中,我不能保證 C# 10 發布時所有東西都會完全如實,
struct record
他談到的第一件事是,目前 record 的實作是使用一個 class 作為基礎物件的,現在還會有一個 record struct 的變體可用,所以基礎型別可以是一個值型別,區別在于,普通的 record 在函式之間傳遞的是參考,而 record struct 是其值的拷貝, record struct 也會支持 with 運算子,
同時,還允許向 record添加運算子,兩種 record 型別都可以,
record Person(string Name, string Email)
{
public static Person operator +(Person first, Person second)
{
// logic goes here
}
}
?
required
C# 團隊關注的目標之一是使物件的初始化變得更容易,這就是為什么可以對 class、struct、record 或 struct record 的屬性添加 required 標記 ,它使得這些屬性必須填寫,這可以通過建構式來完成,也可以通過物件初始化來完成,下面的兩個類的定義是等價的,如果你添加了 required 關鍵字,那么就無法在不設定 Name 屬性的情況下將Person 實體化,編譯器會拋出錯誤,無法編譯,
class Person
{
public required string Name { get; set; }
public DateTime DateOfBirth { get; set; }
}
class Person
{
public Person(string name) => Name = name;
public string Name { get; set; }
public DateTime DateOfBirth { get; set; }
}
?
field
為了進一步的改善屬性,將允許完全擺脫 backing field ,新的關鍵字 field 將提供對上述欄位的訪問,對setter 和 init only 屬性都可以使用,
class Person
{
public string Name { get; init => field = value.Trim(); }
public DateTime DateOfBirth { get; set => field = value.Date; }
}
?
with
在下一個版本中還會有一些有趣的小改進,其實中一個是匿名型別也將支持 with 運算子,
var foo = new
{
Name = "Foo",
Email = "[email protected]"
};
var bar = foo with {Name = "Bar"};
namespace
現在可以創建一個帶有命名空間匯入的檔案,然后在任何地方都可以使用這個匯入,例如,如果有一個很常用的命名空間,幾乎在每個檔案中都使用例如 Microsoft.Extensions.Logging.ILogger ,那么就可以在任何.cs檔案(我建議在 Program.cs 或專門的 Imports.cs )中添加一行 global using Microsoft.Extensions.Logging.ILogger,之后這個命名空間將可以在整個專案中使用,注意,這不適用于整個解決方案! 沒有人能夠預測哪些地方需要匯入,所以它們被分組到每個專案中,
// 譯注:原文并沒有提供代碼示例,為了更好方便大家理解私自添加了一個演示
// Program.cs 檔案
global using System;
// Sample.cs 檔案
// 可以不用再using System;
Console.WriteLine("foo");
?
隨后,還將對命名空間也會有一個優化,現在命名空間需要大括號 {} 來包起來代碼,這就意味著所有代碼至少要縮進一次,為了節省 tab(或四個空格)和螢屏空間,在檔案的任何地方添加一個命名空間,將使所有代碼都屬于該命名空間,有研究表明絕大多數情況下,一個檔案中所有的代碼都屬于同一個命名空間,使用這個方案后,檔案大小隨之減少,這對一個解決方案來說可能并不明顯(即使它包含成千上萬的檔案),但在GitHub/GitLab/BitBucket/... 的規模上,我認為這將為他們節省一些空間,如果有人仍想在一個檔案中包含多個命名空間,使用大括號的選項仍然可用,
// 傳統的方式 LegacyNamespace.cs
namespace LegacyNamespace
{
class Foo
{
// legacy code goes here
}
}
// 簡化的方式 SimplifiedNamespace.cs
namespace SimplifiedNamespace;
class Bar
{
// awesome code goes here
}
lambda
對 lambda 陳述句也會有一些很酷的更新,編譯器將對推斷 lambda 簽名提供更好的支持,而且還可以添加特性,話可以顯式指定回傳型別,以幫助編譯器理解 lambda,
var f = Console.WriteLine;
var f = x => x; // 推斷回傳型別
var f = (string x) => x; // 推斷簽名
var f = [NotNull] x => x; // 添加特性
var f = [NotNull] (int x) => x;
var f = [return: NotNull] static x => x; // 添加特性
var f = T () => default; // 顯式回傳型別
var f = ref int (ref int x) => ref x; // 使用 ref
var f = int (x) => x; // 顯式指定隱式輸入的回傳型別
var f = static void (_) => Console.Write("Help");
感謝 Schooley 提出了一個不那么容易混淆的特性例子
?
interface
最后,將有可能在介面上指定靜態方法和屬性,我知道這將是一個有爭議的話題,就像給介面添加默認實作一樣,我不喜歡它,然而,這可能非常有趣,想象一下,你可以指定一個介面的默認值或指定創建方法,
interface IFoo
{
static IFoo Empty { get; }
static operator +(IFoo first, IFoo second);
}
class Foo : IFoo
{
public static IFoo Empty => new Foo();
public static operator +(IFoo first, IFoo second) => /* do calculation here */;
}
就個人而言,我喜歡這些變化,我最喜歡的是對命名空間的改變和對介面的改進,總之,未來是光明的 C# 的,嗯嗯... (譯注:這里作者玩了一個梗,原文 the future is seeing sharp,see sharp發音類似 C# )
謝謝各位,大家再見,
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/285341.html
標籤:C#
