C# 中的数组切片操作是指从数组中提取子数组的操作。在 .NET Core 2.0 及更高版本中,C# 引入了 Span
以下是数组切片的实现方式、用途以及代码示例。
1. 数组切片操作的实现
1.1 使用Array.Copy
在没有切片支持的情况下,可以通过 Array.Copy 手动提取子数组。
int[] numbers = { 1, 2, 3, 4, 5, 6 };
int[] slice = new int[3];
Array.Copy(numbers, 2, slice, 0, 3); // 从索引 2 开始复制 3 个元素
Console.WriteLine(string.Join(", ", slice)); // 输出: 3, 4, 5
1.2 使用Range和索引器
从 C# 8.0 开始,可以使用 Range 和索引器进行数组切片操作,语法简洁。
int[] numbers = { 1, 2, 3, 4, 5, 6 };
int[] slice = numbers[2..5]; // 从索引 2 开始,到索引 5 之前(不包括 5)
Console.WriteLine(string.Join(", ", slice)); // 输出: 3, 4, 5
特殊索引:
- ^1 表示数组的最后一个元素的索引。
- .. 表示范围操作符。
示例:
int[] sliceFromEnd = numbers[^3..]; // 从倒数第三个元素开始切片
Console.WriteLine(string.Join(", ", sliceFromEnd)); // 输出: 4, 5, 6
1.3 使用Span和Memory
Span
int[] numbers = { 1, 2, 3, 4, 5, 6 };
Span slice = numbers.AsSpan(2, 3); // 从索引 2 开始,长度为 3
foreach (var num in slice)
{
Console.WriteLine(num); // 输出: 3, 4, 5
}
2. 数组切片的用途
- 提取子数组
- 从大数组中获取部分内容,例如分页、处理部分数据。
- 性能优化
- 使用 Span
避免了内存分配和拷贝操作,提升性能。 - 数据处理
- 提取特定范围的数据进行过滤、转换或操作。
- 分段处理
- 适用于图像处理、信号处理等需要处理数组块的场景。
3. 数组切片的优点和注意事项
优点
- 简洁:Range 和 Span
提供直观的切片语法。 - 高效:Span
避免了数组的拷贝,直接在原内存上操作。 - 灵活性:支持从前到后和从后到前的索引。
注意事项
- 切片操作时,必须确保索引范围合法,否则会抛出 IndexOutOfRangeException。
- 使用 Span
的时候要注意其作用域,不能脱离其数组或内存的生命周期。
4. 示例:分页操作
通过数组切片实现简单的分页功能:
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int pageSize = 3;
int pageNumber = 2; // 获取第 2 页的数据
int startIndex = (pageNumber - 1) * pageSize;
int[] pageData = numbers[startIndex..(startIndex + pageSize)];
Console.WriteLine(string.Join(", ", pageData)); // 输出: 4, 5, 6
总结
数组切片在 C# 中是一个方便、强大的功能,尤其是在数据处理、分页和性能优化等场景中。通过 Range 和 Span