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# 的集合表达式和展开运算符提供了:

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

  • 更直观的集合合并方式

  • 更好的代码可读性

  • 编译器优化的性能优势

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

相关推荐
iCxhust1 小时前
c# U盘映像生成工具
开发语言·单片机·c#
yangzhi_emo2 小时前
ES6笔记2
开发语言·前端·javascript
jz_ddk3 小时前
[学习] C语言数学库函数背后的故事:`double erf(double x)`
c语言·开发语言·学习
萧曵 丶3 小时前
Rust 所有权系统:深入浅出指南
开发语言·后端·rust
xiaolang_8616_wjl3 小时前
c++文字游戏_闯关打怪2.0(开源)
开发语言·c++·开源
收破烂的小熊猫~3 小时前
《Java修仙传:从凡胎到码帝》第四章:设计模式破万法
java·开发语言·设计模式
nananaij4 小时前
【Python进阶篇 面向对象程序设计(3) 继承】
开发语言·python·神经网络·pycharm
阿蒙Amon4 小时前
为什么 12 版仍封神?《C# 高级编程》:从.NET 5 到实战架构,进阶者绕不开的必修课
开发语言·c#