C# 12

前言

C# 12 是 .NET 8 版本推出的,目前還在 RC 階段。預計 2023 年 11 月份就會正式推出了。

想提早玩玩的話可以使用用 Visual Studio Preview

 

參考

Docs – What's new in C# 12

 

Primary Constructors

參考:

Docs – Tutorial: Explore primary constructors

Docs – Primary constructors

YouTube – The New Constructor Type Coming in C# 12 is Weird

C# 9.0 推出的 Record 就有 Primary constructors 的概念。

它的 definition 非常短

public record Dimension(int Width, int Height);

相同的邏輯,class 就很長很繁瑣。

public class Dimension {
    public int Width { get; set; }
    public int Height { get; set; }

    public Dimension(int width, int height) { 
        Width = width; 
        Height = height;
    }
}

於是,C# 12 也讓 class 和 struct 有了 primary constructors 的功能。

但是要注意哦,它們有一些些微妙的不同,很容易讓你掉坑。

Class primary constructors != Record primary constructors

public class Dimension(int width, int height);

上面這句和 Record 語法類似,但是效果卻差很多。

首相,它的參數是 camelCase,Record 是 PascalCase,爲什麼呢?

因爲 Record 的參數是 public property,而 class 的 parameter 是 private field。

所以,property 的寫法應該是長這樣的。

public class Dimension(int width, int height) {
    public int Width { get; set; } = width;
    public int Height { get; set; } = height;
}

不管怎樣,它還是比之前短了一些。還是不錯用的。

Parameters can be use anywhere

參數不僅僅可以用於 assign to property,它也可以在方法中使用。

public class Dimension(int width, int height) 
{
    public int Sum() {
        return width + height;
    }
}

原因上面提到了,paramters 其實是 private filed 來的

我們把代碼放到 sharplab.io 查看就明白了

簡單說,primary constructors 就是語法糖,它就是替你寫了一個 constructor 還有 private fields.

Dependency Injection

C# 11

public class Dimension
{
    private readonly Service _service;
    public Dimension(Service service) {
        _service = service;
    }
}

C# 12

public class Dimension(Service service)
{
    private readonly Service _service = service;
}

如果你不是很在意 readonly 的話,可以省略

public class Dimension(Service service) {

}

本來聽說會支持 readonly 語法

public class Dimension(readonly Service service) {

}

但最後視乎是被否決掉了。

總結

C# 12 以後,Record, Class, Struct 又又又更加像了,更傻傻分不清楚了,更容易掉坑了。

記住,class 的 primary constructors 是 constructor + private fields, Record 則是 constructor + public properties。

 

Collection Expressions

日常我們定義 collection 的方式

var numbers = new List<int> { 1, 2, 3 };

上面是 var 推導類型的 defined 寫法

換成先 declare 類型是這樣

List<int> numbers = new() { 1, 2, 3 };

C# 12 對上面這句語法做了優化,現在只需要這樣寫

List<int> numbers = [1, 2, 3];

它只是語法糖而已,通過 sharplab.io 查看

轉譯出來就是 new List + add item

Spread Operator

寫過 JavaScript 的人對 spread operator 應該不陌生了。C# 12 也有了這個功能。

var numbers = new List<int> { 1, 2, 3 };
List<int> numbers2 = [..numbers, 4, 5]; // 語法正確
var number3 = new List<int> { ..numbers2, 6, 7 }; // 語法錯誤哦

 

Default lambda parameters

C# 11 lambda 是不支持 default parameter value 的。C# 12 以後支持了。

C# 12

如果動態創建表達式樹 for default parameters 我還沒有研究。以後補上。

 

Alias any type

Alias type 有點像 TypeScript 的 Type Aliases,但也不完全一樣。

我目前是沒有想到哪裏可以用它啦。

using Point = Coordinate;

public class Coordinate {
    public int X { get; set; }
    public int Y { get; set; }
}

它可以完全用一個 alias 別名取代任何類型,就真的是 rename 而已哦。

var point = new Point();

上面這個在 TypeScript 是做不到的哦

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章