C#.NET 集合表达式详解:新时代的集合初始化方式

简介

集合表达式(Collection Expressions)是 C# 12.0(随 .NET 8.0 发布于 2023 年)引入的一项新特性,用于以简洁、声明式的方式创建和初始化集合(如数组、列表、字典等)。集合表达式通过 [...] 语法提供了一种更直观的方式来定义集合,减少样板代码并提高可读性。

背景和作用

集合表达式旨在解决传统集合初始化(如 new List<T> { ... }new[] { ... })的冗长和不一致问题,灵感来源于 PythonJavaScript 的列表推导式。它在以下场景中特别有用:

  • 数据初始化:快速定义数组、列表或字典。

  • 批量操作:简化 MySqlBulkLoader 的数据表填充。

  • API 输入/输出:处理 JSON 数据或响应集合。

  • 缓存管理:初始化 MemoryCache 的键值对。

  • 定时任务:结合 Cronos 处理批量数据。

核心概念

传统初始化 vs 集合表达式

csharp 复制代码
// 传统方式  
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];  

语法结构

csharp 复制代码
// 基础形式  
[element1, element2, ..., elementN]  

// 空集合  
var empty = [];  

// 嵌套集合  
int[][] matrix = [[1, 2], [3, 4], [5, 6]];  

支持的所有集合类型

集合类型 示例 编译器转换机制
数组 int[] arr = [1, 2, 3]; 直接优化为 new int[] { ... }
List List list = [1, 2, 3]; 调用 List.CollectionsMarshalHelper.Create()
Span Span span = [1, 2, 3]; 栈分配或缓冲区重用
ReadOnlySpan ReadOnlySpan ros = ['a','b']; 同 Span
ImmutableArray ImmutableArray ia = [1,2,3]; 调用 ImmutableArray.Create()
自定义集合 实现 IEnumerable + Add 方法 编译器生成 Add 调用序列

✅ 所有实现 IEnumerable 且有 Add 方法的类型都支持

主要功能

简洁语法:

  • 使用 [...] 替代 new List<T> { ... }new[] { ... }

  • 支持多种集合类型(数组、List<T>Span<T>、字典等)。

扩展运算符:

  • 使用 .. 展开现有集合(如合并数组或列表)。

类型推断:

  • 自动推断目标集合类型,减少显式类型声明。

多场景支持:

  • 初始化集合、传递参数、返回结果。

  • 支持 LINQ、异步操作和并发场景。

与现有集合兼容:

  • 无缝转换到 IEnumerable<T>ICollection<T> 等。

核心语法

集合表达式使用 [...] 语法,支持以下形式:

  • 基本初始化:
csharp 复制代码
int[] numbers = [1, 2, 3]; // 等价于 new[] { 1, 2, 3 }
List<string> names = ["Alice", "Bob"]; // 等价于 new List<string> { "Alice", "Bob" }
  • 扩展运算符(..):
csharp 复制代码
int[] moreNumbers = [1, 2, ..numbers, 4]; // 展开 numbers,生成 [1, 2, 1, 2, 3, 4]
  • 空集合:
csharp 复制代码
int[] empty = []; // 等价于 Array.Empty<int>()
  • 嵌套集合:
csharp 复制代码
int[][] jagged = [[1, 2], [3, 4]]; // 锯齿状数组
  • 字典初始化:
csharp 复制代码
Dictionary<string, int> scores = ["Alice": 90, "Bob": 85]; // 等价于 new Dictionary<string, int> { ["Alice"] = 90, ["Bob"] = 85 }
  • 目标类型:

    • 支持 IEnumerable<T>、ICollection<T>、List<T>、数组、Span<T> 等。

    • 编译器根据上下文推断类型:

    csharp 复制代码
    IEnumerable<int> enumerable = [1, 2, 3]; // 推断为数组
  • 自定义集合支持

csharp 复制代码
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"];  
相关推荐
专注VB编程开发20年6 小时前
C#全面超越JAVA,主要还是跨平台用的人少
java·c#·.net·跨平台
小猪快跑爱摄影9 小时前
【AutoCad 2025】【C#】零基础教程(四)——MText 常见属性
c#·autocad
炼钢厂11 小时前
C#6——DateTime
c#
Lv117700812 小时前
Visual Studio中的多态
ide·笔记·c#·visual studio
wuguan_12 小时前
C#:多态函数重载、态符号重载、抽象、虚方法
开发语言·c#
我不是程序猿儿12 小时前
【C#】ScottPlot的Refresh()
开发语言·c#
工程师00713 小时前
C# 基于 HSL 与基恩士 PLC 通信
c#·mc协议·基恩士plc
张人玉16 小时前
c# DataSet 类
数据库·c#·dataset
秦苒&16 小时前
【C语言】详解数据类型和变量(一):数据类型介绍、 signed和unsigned、数据类型的取值范围、变量、强制类型转换
c语言·开发语言·c++·c#
一个帅气昵称啊16 小时前
.Net通过EFCore和仓储模式实现统一数据权限管控并且相关权限配置动态生成
.net·efcore·仓储模式