2026-10-25 10:33:29
C# 8.0 引入的切片语法糖(..)确实是一个非常实用的功能,它允许开发者以简洁的方式对数组、字符串等类型进行切片操作。以下是对该功能的详细解析:
一、切片语法糖的基本用法1. 提取前N个元素var myarr = new string[] { "10", "20", "30", "40", "50", "60", "70", "80", "90", "100" };var query1 = myarr[0..3]; // 提取前3个元素切片操作在编译后会被转换为对 RuntimeHelpers.GetSubArray<T> 方法的调用:
// 编译前var query1 = myarr[0..3];// 编译后string[] query = RuntimeHelpers.GetSubArray<string>(myarr, new Range(0, 3));2. Range 和 Index 类型该方法用于计算切片的起始位置和长度:
public ValueTuple<int, int> GetOffsetAndLength(int length){ Index start = this.Start; int num; if (start.IsFromEnd) { num = length - start.Value; } else { num = start.Value; } Index end = this.End; int num2; if (end.IsFromEnd) { num2 = length - end.Value; } else { num2 = end.Value; } return new ValueTuple<int, int>(num, num2 - num);}如果 Start 或 End 是反向索引(IsFromEnd = true),则从数组末尾开始计算。
返回的元组包含切片的起始位置和长度。
最终的切片操作是通过 Buffer.Memmove 方法完成的,该方法高效地拷贝内存中的数据:
public static T[] GetSubArray<T>(T[] array, Range range){ ValueTuple<int, int> offsetAndLength = range.GetOffsetAndLength(array.Length); int item = offsetAndLength.Item1; int item2 = offsetAndLength.Item2; T[] array3 = new T[item2]; Buffer.Memmove<T>(Unsafe.As<byte, T>(array3.GetRawSzArrayData()), Unsafe.Add<T>(Unsafe.As<byte, T>(array.GetRawSzArrayData()), item), (ulong)item2); return array3;}三、切片语法糖的优势1. 简洁性等价于 str.Substring(1, 2)。
C# 8.0 引入的切片语法糖(..)是一个强大的功能,它通过简洁的语法和高效的底层实现,极大地简化了数组和字符串的切片操作。无论是提取前N个元素、最后N个元素,还是指定范围的元素,切片语法糖都能以直观的方式完成任务。此外,它还减少了代码量,提高了可读性和性能。对于熟悉 Python 的开发者来说,这一语法糖无疑是一个亲切的惊喜。