What's New in C# 12 === Video : https://www.youtube.com/watch?v=by-GL-SjHdc&list=PLdo4fOcmZ0oULyHSPBx-tQzePOYlhvrAU > 影片只有介紹部分 C# 12 的 feature,全部列表請看 Reference 區段裡面的 What's new in C# 12 ## alias alais 宣告支援度擴展:可以宣告 primitive type 為 Alias,也支援 Tuple, unsafe - e.g. - `using Grade = decimal` - `using Grade = (string Course, decimal Value)` - `using unsafe Grade = decimal*;` ## 在 class 也支援 `primary constructor` 宣告方式 ``` C# public class Student(string name, int id, Grade[] grades) { public Student(string name, int id) : this(name, id, Array.Empty<Grade>()) } ``` - 在 record 這種宣告方式的參數會被當成 public property,但是在 class 則是視為 **method parameter** - 所以如果要 屬性、變數 的話仍然要自己宣告 ``` C# public class Student(string name, int id, Grade[] grades) { public string Name { get; set; } = name; } ``` - 也因為是 parameter,雖然 compiler 會幫你做事情,但有些寫法上會有些限制,可能會有問題 - e.g. ``` C# public class Student(string name, int id, Grade[] grades) { public string Name { get; set; } = name; // 這邊會有 compiler warning puglic int Length => name.Length; } ``` - 使用 Primary constructor 的宣告方式,其他的 constructor 的宣告一定最後需要串回 primary constructor 否則會有 compile error - 新版的 VS 的 refactor 功能會支援在 primary contructor 的宣告方式 <=> 一班宣告方式 的轉換 - [觀點] 感覺這概念類似 javascript 的 [Constructor Function](https://javascript.alphacamp.co/constructor-function.html),就是用一個 method 來宣告一個 object 的長相 ## Collection Expression - 支援 `[]` 當作 collection 使用 - 空的可以寫成 `[]` - 可以用於幾乎任何的 collection 上 ``` C# public void MethodA(ImmutableList<int> items) { } MethodA([1, 2, 3]); MethodA([]); ``` - 自己的寫的 class 要支援 collection expression 需要在 class 上新增 `CollectionBuilder` 的 attribute` - attribute 會指定哪一個 class 的哪一個 method 會負責建立轉換 - collection expression 會被視為 `ReadOnlySpan<T>` 所以要有一個 method 是支援傳入 `ReadOnlySpan<T>` 當參數的 method - e.g. ```C# [CollectionBuilder(typeof(ImmutableArray), "Create")] public readonly struct ImmutableArray<T> // 會有 ImmutableArray 的 class public static ImmutableArray { // 裡面需要有這個 method public static ImmutableArray<T> Create<T>(ReadOnlySpan<T> items) } ``` - 不是所有的 .net built-in class 支援 collection expression 是透過這個 attribute 的支援,而是底層的實做做掉了 - e.g. `List`, `IEnumerable<T>` - `..` spread operator - [觀點] 是的,你沒看錯是 spread operator XD 跟 javascript 致敬的 [Spread syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax) - pattern 支援 ``` C# public class Student(string name, int id, ImmutableArray<Grade> grades) { public Grade GPA => grades switch { [] => 4.0m, [var grade] => grade, [.. var all] => all.Average() } } // 第一個 switch case var s1 = new Student("Name1", 1, []); // 第三個 swtich case var s3 = new Student("Name1", 1, [1.0m, 2.0m, 3.0m]); ``` ## Reference - [What's new in C# 12](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-12)