.NET9 - 新功能體驗(一)

IT规划师發表於2024-11-21

被微軟形容為“迄今為止最高效、最現代、最安全、最智慧、效能最高的.NET版本”——.NET 9已經發布有一週了,今天想和大家一起體驗一下新功能。

此次.NET 9在效能、安全性和功能等方面進行了大量改進,包含了數千項的修改,今天主要和大家一起體驗我們常用有變化的功能。

01、安裝

首先可以在命令列中透過dotnet --list-sdks指令檢視是否以安裝.NET9。

安裝方式主要有兩種,第一種透過直接下載.NET9 SDK安裝。

第二種方式透過更新IDE Visual Studio至17.12.0或之後的版本,比如我的IDE是17.11.6,選擇更新即可,如果是更老的版本,比如17.11.4則需要更新兩次才行。

再次執行dotnet --list-sdks命令,發現已安裝成功,結果如下:

02、新的轉義序列

本次C#13新引入了 \e 作為 ESC (Escape)字元 Unicode U+001B 的字元文字轉義序列。而以前使用的是 \u001b 或 \x1b。

ESC (Escape) 字元(ASCII 編碼值為 27,十六進位制為 0x1b)是一種控制字元,可以用於 終端控制和文字格式化。它本身代是不可見字元,主要作用標誌著後續字元序列的開始,這些序列會指定終端執行特定的操作,如改變文字顏色、設定文字樣式、清屏、移動游標等。

我們舉一個例子,比如“ESC[31m ”表示把文字顏色設定為紅色,我們把ESC改為轉義序列,程式碼如下:

static void Main(string[] args)
{
    var colorRed = "\x1b[31m紅色文字";
    Console.WriteLine(colorRed);
    Console.ReadKey();
}

執行效果如下:

如果單獨使用ESC (Escape)字元的轉義序列則表示其後接著的字元不可見,我們可以用\u001b和\x1b看看效果,結果如下,發現看字沒有展示出來:

然後我們把\u001b和\x1b改為\u001b1和\x1b1,再看一下效果:

從上圖可以發現使用\u001b1結果還是\u001b後面一個字元看不見,而使用\x1b1後變成問號“?”了,這是因為\x1b1整體被識別為一個更長的十六進位制序列,而不是單純的控制字元了,這就產生了歧義,因此不建議使用\x1b,因而這次新增了跳脫字元\e,效果如下。

03、隱式索引訪問

現在物件初始值設定項表示式中允許隱式“從末尾開始”索引運算子[^]。

我們來看一個例子,首先建立了一個ImplicitIndex類並且包含一個Numbers屬性,該屬性是一個長度為 5 的整數陣列。

現在我們可以在初始化類ImplicitIndex時初始化屬性Numbers,並使用“從末尾開始”索引運算子來填充陣列值。

我們先看看在.NET8中的效果,滑鼠移到錯誤上可以看到老版本是不支援該功能的,如下圖:

而使用.NET9則可以。

04、params引數增強

之前params只支援陣列,而現在params引數支援更多的集合型別,包括 Span、ReadOnlySpan、IEnumerable 等等。這使得我們可以更加靈活的傳入集合引數,而不用先把集合轉成陣列後再傳輸。

public static void PrintNumbers(params int[] numbers) { }
public static void PrintNumbers(params List<string> numbers) { }
public static void PrintNumbers(params HashSet<int> numbers) { }
public static void PrintNumbers(params SortedSet<int> numbers) { }
public static void PrintNumbers(params IList<int> numbers) { }
public static void PrintNumbers(params ICollection<int> numbers) { }
public static void PrintNumbers(params IEnumerable<int> numbers) { }
public static void PrintNumbers(params Span<int> numbers) { }
public static void PrintNumbers(params ReadOnlySpan<int> numbers) { }

params 關鍵字允許方法接收一個可變數量的引數,通常是單一型別的引數集合。params 的引數通常可以是陣列、集合或其他實現了 IEnumerable 介面的型別,但有一些限制,比如以下型別雖然實現了IEnumerable 介面,但是並不受支援。

public static void PrintNumbers(params Dictionary<int, int> numbers) { }
public static void PrintNumbers(params SortedList<int, int> numbers) { }
public static void PrintNumbers(params LinkedList<int> numbers) { }
public static void PrintNumbers(params Queue<int> numbers) { }
public static void PrintNumbers(params Queue numbers) { }
public static void PrintNumbers(params Stack<int> numbers) { }
public static void PrintNumbers(params Stack numbers) { }
public static void PrintNumbers(params Hashtable numbers) { }

05、鎖物件

本次更新引入新的鎖型別System.Threading.Lock,用於實現互斥。在之前的版本中通常透過object型別進行加鎖,而現在有了專門的Lock型別用來加鎖。

新的Lock型別會使得程式碼更乾淨、更安全、更高效。

在新的鎖定機制中EnterScope替換了Monitor底層實現。同時它遵循Dispose模式返回ref struct,因此可以與using語句結合使用。

我們一起看看下面程式碼示例:

// .NET 9 之前
public class LockExampleNET9Before
{
    private readonly object _lock = new();
    public void Print()
    {
        lock (_lock)
        {
            Console.WriteLine("我們是老的鎖");
        }
    }
}
// .NET 9
public class LockExampleNET9
{
    private readonly Lock _lock = new();
    public void Print()
    {
        lock (_lock)
        {
            Console.WriteLine("我們是 .NET 9 新鎖");
        }
    }
    public async Task LogMessageAsync(string message)
    {
        using (_lock.EnterScope())
        {
            Console.WriteLine("我們是 .NET 9 新鎖,可以和using一起使用");
        }
    }
}

06、生成UUID v7

我們經常在實體中使用Guid作為主鍵,並且透過Guid.NewGuid()可以很方便的生成一個新的Guid,而此方法生成的Guid是依據UUID第四個版本規範生成的。

當前已經可以透過Guid.CreateVersion7()方法建立UUID第七個版本,這個版本UUID主要功能就是包含了時間戳,資料結構如下:

| 48位時間戳 | 12位隨機 | 62位隨機 |

這也意味著v7版本的UUID可以按時間排序了,在資料庫中使用起來更方便,同時Guid.CreateVersion7()方法還有一個過載方法接收DateTimeOffset型別時間戳,用來透過指定時間建立UUID。

static void Main()
{
    // v4 UUID
    var guid_v4 = Guid.NewGuid();
    // v7 UUID
    var guid_v7 = Guid.CreateVersion7();
    // v7 UUID with timestamp
    var guid_v7_time = Guid.CreateVersion7(TimeProvider.System.GetLocalNow()); 
    Console.ReadKey();
}

:測試方法程式碼以及示例原始碼都已經上傳至程式碼庫,有興趣的可以看看。https://gitee.com/hugogoos/Planner

相關文章