C# 集合表达式和展开运算符 (..) 详解

集合表达式 (Collection Expressions)

C# 12 引入了集合表达式,提供了一种更简洁的方式来创建和初始化集合。

基本语法

cpp 复制代码
// 创建数组
int[] array = [1, 2, 3];

// 创建列表
List<int> list = [1, 2, 3];

// 创建跨度(Span)
Span<int> span = [1, 2, 3];

支持的集合类型

集合表达式支持多种集合类型:

  • 数组 (T[])

  • List<T>

  • Span<T> 和 ReadOnlySpan<T>

  • 实现了 IEnumerable<T> 并有合适 Add 方法的类型

展开运算符 (..)

展开运算符用于将现有集合的元素"展开"到新的集合中。

基本用法

cpp 复制代码
int[] numbers1 = [1, 2, 3];
int[] numbers2 = [4, 5, 6];

// 合并两个数组
int[] combined = [.. numbers1, .. numbers2]; 
// [1, 2, 3, 4, 5, 6]

// 添加额外元素
int[] withExtra = [.. numbers1, 10, 20, .. numbers2]; 
// [1, 2, 3, 10, 20, 4, 5, 6]

实际应用示例

创建新集合

cpp 复制代码
// 传统方式
List<string> oldWay = new List<string> { "A", "B", "C" };

// 新方式
List<string> newWay = ["A", "B", "C"];

合并集合

cpp 复制代码
List<int> first = [1, 2, 3];
List<int> second = [4, 5, 6];

// 合并两个列表
List<int> merged = [.. first, .. second];

与现有API结合

cpp 复制代码
// 传递给需要IEnumerable的方法
ProcessNumbers([1, 2, 3, 4, 5]);

void ProcessNumbers(IEnumerable<int> numbers)
{
    foreach (var num in numbers)
    {
        Console.WriteLine(num);
    }
}

性能考虑

集合表达式通常能提供更好的性能

  • 对于数组,编译器会优化为直接的数组初始化

  • 对于列表,编译器会使用最有效的方式初始化

高级用法

多维集合

cpp 复制代码
int[][] matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];

自定义集合

要使自定义集合支持集合表达式,需要实现:

  • IEnumerable<T>

  • 有一个可访问的 Add 方法

cpp 复制代码
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();
    
    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}

// 使用
CustomCollection<int> custom = [1, 2, 3];

注意事项

  • 展开运算符 (..) 只能用于集合表达式内部

  • 集合表达式不能用于 null 值

  • 目标类型必须明确(不能用于 var 推断)

与传统方式的比较

特性 集合表达式 传统方式
语法简洁性 ✅ 高(单行简洁语法) ❌ 低(需要更多样板代码)
可读性 ⭐⭐⭐ 高(直观表达意图) ⭐⭐ 中等(结构略显冗长)
灵活性 🔄 高(支持混合元素和展开) 🔄 高(但语法更复杂)
性能 ⚡ 优化更好(编译器特殊处理) ⏳ 一般(标准初始化流程)
版本要求 🆕 C# 12+ 🏛️ 所有版本

总结

C# 的集合表达式和展开运算符提供了:

  • 更简洁的集合初始化语法

  • 更直观的集合合并方式

  • 更好的代码可读性

  • 编译器优化的性能优势

建议在新项目中使用这些特性,特别是在需要频繁创建或合并集合的场景中。

相关推荐
遇印记4 小时前
传输层,网络层
运维·服务器·网络·windows·学习
死磕音视频5 小时前
让小模型做选择题:限定候选项并读取 logits 概率的入门实践(附 Python 代码)
开发语言·python·大模型·文本分类·transformers
又見山6 小时前
Obsidian 跨平台同步实测:Nutstore Sync 在 Windows、Mac、Linux、iOS、Android 全平台综合测评
windows·macos·obsidian·obsidian同步·obsidian教程·obsidian入门·obsidian笔记库搭建
顽疲7 小时前
Java vue 养老系统源码详解:月账单 care_month_bill 与 Quartz 扣费 Job 实践
java·开发语言·vue.js·vue养老·springboot养老·java养老
jearry7 小时前
一个编辑器两个内核:Markdown 实时视图与源码视图并存时的竞态、光标锚点与 PDF 导出
windows·markdown
Wang's Blog7 小时前
Java 项目实战: 交友项目 - 安装开发工具与环境准备
java·开发语言·交友
逆向编程7 小时前
DirectX修复工具下载安装教程-Windows系统DLL缺失检测修复完整图文步骤
windows
曹牧8 小时前
C#:输入的字符串格式不正确
c#
钱栈up9 小时前
电脑卡死7分钟,日志断在13:56:03:一次Windows硬挂死的根因复盘
windows
程序喵大人9 小时前
【C++入门】编译链接模型 - 07 链接器怎样把符号对上号
开发语言·c++·编译器·编译链接·链接器