Collection Expressions,一個頗為方便的新功能,讓我們繼續看下去。
Collections Expressions 中文被稱為集合表達式,名字聽起來很厲害的樣子,說穿了就是更先進的集合初始化設定式。
目前這個功能可以用在陣列、Span<T> and ReadOnlySpan<T> 以及支持集合初始化設定式的集合型別 (但 Dictionary<T1,T2> 偏偏不行)。
不囉嗦,先來幾個簡單的範例:
int[] array = [1, 2, 3, 4, 5, 6, 7, 8];
List<string> list = ["one", "two", "three"];
Span<char> span = ['a', 'b', 'c', 'd', 'e', 'f', 'h', 'i'];
int[][] towArray = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
ObservableCollection<string> collection = ["A", "B", "C"];
使用這個表達式的時候,左邊的回傳型別必須明確指派,不可以偷懶用 var。
還有一個很有趣的用法,像這樣:
IEnumerable<int> GetSomethings() => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
不過我覺得上面回傳 IEnumerable<T> 的寫法看來雖然很炫,但是展開後的程式碼實在有點奇妙,會像這樣 (第一行我就直接用新語法表示,偷懶不展開了):
IEnumerable<int> GetSomethings2()
{
int[] array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
<>z__ReadOnlyArray<int> readOnlyCollection =new <>z__ReadOnlyArray<int>(array);
return readOnlyCollection;
}
會出現一個奇妙的型別 <>z__ReadOnlyArray<int> ,不要試圖在你的 C# 程式碼用這個型別,其中一個是因為這個型別的命名在 C# 是不合法的 (但 IL 層級是合法的,所以很多奇妙的型別都會帶<> 開頭),再來他是編譯器搞出來的,除非你硬用反射去搞他,不然也用不了。
另外一個有趣的部份是配合散布運算子 (spread operator),這個運算子的長相就是兩個點啦。
List<int> list1 = [10, 11, 12];
List<int> list2 = [.. list1, 20, 30];
int[] array = [.. list1, 99, 98, .. list2];
Console.WriteLine(string.Join(", ", array));
所以 list2 就是 list1 的元素加上新增的 20, 30;array 就是 list1 + 99 + 98 + list2,用起來的爽度很高。