- 集合表达式 (`Collection Expressions`)
- 基本语法
- 支持的集合类型
- 展开运算符 (`..`)
- 基本用法
- 实际应用示例
- 创建新集合
- 合并集合
- 与现有API结合
- 性能考虑
- 高级用法
- 多维集合
- 自定义集合
- 注意事项
- 与传统方式的比较
- 总结
集合表达式 (Collection Expressions
)
C# 12
引入了集合表达式,提供了一种更简洁的方式来创建和初始化集合。
基本语法
// 创建数组
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
方法的类型
展开运算符 (..
)
展开运算符用于将现有集合的元素"展开"到新的集合中。
基本用法
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]
实际应用示例
创建新集合
// 传统方式
List<string> oldWay = new List<string> { "A", "B", "C" };// 新方式
List<string> newWay = ["A", "B", "C"];
合并集合
List<int> first = [1, 2, 3];
List<int> second = [4, 5, 6];// 合并两个列表
List<int> merged = [.. first, .. second];
与现有API结合
// 传递给需要IEnumerable的方法
ProcessNumbers([1, 2, 3, 4, 5]);void ProcessNumbers(IEnumerable<int> numbers)
{foreach (var num in numbers){Console.WriteLine(num);}
}
性能考虑
集合表达式通常能提供更好的性能
-
对于数组,编译器会优化为直接的数组初始化
-
对于列表,编译器会使用最有效的方式初始化
高级用法
多维集合
int[][] matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
自定义集合
要使自定义集合支持集合表达式,需要实现:
-
IEnumerable<T>
-
有一个可访问的
Add
方法
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#
的集合表达式和展开运算符提供了:
-
更简洁的集合初始化语法
-
更直观的集合合并方式
-
更好的代码可读性
-
编译器优化的性能优势
建议在新项目中使用这些特性,特别是在需要频繁创建或合并集合的场景中。