簡介
集合表達式(Collection Expressions)是 C# 12.0(隨 .NET 8.0 發佈於 2023 年)引入的一項新特性,用於以簡潔、聲明式的方式創建和初始化集合(如數組、列表、字典等)。集合表達式通過 [...] 語法提供了一種更直觀的方式來定義集合,減少樣板代碼並提高可讀性。
背景和作用
集合表達式旨在解決傳統集合初始化(如 new List<T> { ... } 或 new[] { ... })的冗長和不一致問題,靈感來源於 Python 和 JavaScript 的列表推導式。它在以下場景中特別有用:
- 數據初始化:快速定義數組、列表或字典。
- 批量操作:簡化
MySqlBulkLoader的數據表填充。 API輸入/輸出:處理JSON數據或響應集合。- 緩存管理:初始化
MemoryCache的鍵值對。 - 定時任務:結合
Cronos處理批量數據。
核心概念
傳統初始化 vs 集合表達式
// 傳統方式
List<int> list1 = new List<int> { 1, 2, 3 };
int[] array1 = new int[] { 1, 2, 3 };
// C# 12 集合表達式
List<int> list2 = [1, 2, 3];
int[] array2 = [1, 2, 3];
Span<int> span = [1, 2, 3];
語法結構
// 基礎形式
[element1, element2, ..., elementN]
// 空集合
var empty = [];
// 嵌套集合
int[][] matrix = [[1, 2], [3, 4], [5, 6]];
支持的所有集合類型
| 集合類型 | 示例 | 編譯器轉換機制 |
|---|---|---|
| 數組 | int[] arr = [1, 2, 3]; | 直接優化為 new int[] { ... } |
| List<T> | List<int> list = [1, 2, 3]; | 調用 List<T>.CollectionsMarshalHelper.Create() |
| Span<T> | Span<int> span = [1, 2, 3]; | 棧分配或緩衝區重用 |
| ReadOnlySpan<T> | ReadOnlySpan<char> ros = ['a','b']; | 同 Span<T> |
| ImmutableArray<T> | ImmutableArray<int> ia = [1,2,3]; | 調用 ImmutableArray.Create() |
| 自定義集合 | 實現 IEnumerable<T> + Add 方法 | 編譯器生成 Add 調用序列 |
✅ 所有實現 IEnumerable<T> 且有 Add 方法的類型都支持
主要功能
簡潔語法:
- 使用
[...]替代new List<T> { ... }或new[] { ... }。 - 支持多種集合類型(數組、
List<T>、Span<T>、字典等)。
擴展運算符:
- 使用
..展開現有集合(如合併數組或列表)。
類型推斷:
- 自動推斷目標集合類型,減少顯式類型聲明。
多場景支持:
- 初始化集合、傳遞參數、返回結果。
- 支持
LINQ、異步操作和併發場景。
與現有集合兼容:
- 無縫轉換到
IEnumerable<T>、ICollection<T>等。
核心語法
集合表達式使用 [...] 語法,支持以下形式:
- 基本初始化:
int[] numbers = [1, 2, 3]; // 等價於 new[] { 1, 2, 3 }
List<string> names = ["Alice", "Bob"]; // 等價於 new List<string> { "Alice", "Bob" }
- 擴展運算符(..):
int[] moreNumbers = [1, 2, ..numbers, 4]; // 展開 numbers,生成 [1, 2, 1, 2, 3, 4]
- 空集合:
int[] empty = []; // 等價於 Array.Empty<int>()
- 嵌套集合:
int[][] jagged = [[1, 2], [3, 4]]; // 鋸齒狀數組
- 字典初始化:
Dictionary<string, int> scores = ["Alice": 90, "Bob": 85]; // 等價於 new Dictionary<string, int> { ["Alice"] = 90, ["Bob"] = 85 }
-
目標類型:
- 支持
IEnumerable<T>、ICollection<T>、List<T>、數組、Span<T>等。 - 編譯器根據上下文推斷類型:
IEnumerable<int> enumerable = [1, 2, 3]; // 推斷為數組 - 支持
- 自定義集合支持
public class CustomCollection<T> : IEnumerable<T>
{
private readonly List<T> _items = new();
public void Add(T item) => _items.Add(item);
public IEnumerator<T> GetEnumerator() => _items.GetEnumerator();
}
// 使用集合表達式初始化
CustomCollection<string> tags = ["dotnet", "csharp"];