编辑
2025-09-27
C#
00

目录

摘要
正文
Span 的特点
应用场景
示例 1:基本用法
示例 2:字符串切片
示例 3:内存复制
示例 4:与 Memory<T> 结合使用

摘要


Span 是 C# 中引入的一个结构类型,用于提供对连续内存区域的类型安全访问。这个特性最初在 .NET Core 2.1 中引入,旨在优化性能,尤其是在处理数组、字符串和其他类型的缓冲区时。Span 可以看作是一个窗口,它允许开发者在不复制数据的情况下操作内存。

正文


Span 的特点

  • 类型安全:Span 是泛型的,确保只能访问指定类型的数据。
  • 内存效率:它允许在不创建新数组或字符串副本的情况下操作数据,减少了内存分配和垃圾回收的压力。
  • 栈分配:Span 是一个栈上的结构,它不会导致堆分配。
  • 切片操作:可以轻松地从现有的 Span 创建新的 Span,而不会发生数据复制。
  • 安全性:Span 不能跨越异步方法的边界,因为它可能指向非托管的内存,这样可以避免潜在的数据竞争和同步问题。

应用场景

  • 解析数据:在解析文件或网络数据流时,可以使用 Span 来避免不必要的内存复制。
  • 性能关键型应用:对于需要高性能内存操作的应用程序,如游戏、高频交易系统等。
  • 内存管理:在需要精细控制内存分配和回收的场景中,Span 提供了更大的灵活性。
  • 缓冲区操作:对于需要在缓冲区上执行复杂操作的场景,Span 提供了简单的API。

示例 1:基本用法

C#
static void Main(string[] args) { ProcessBytes(System.Text.Encoding.UTF8.GetBytes("0123456789")); } static void ProcessBytes(byte[] data) { // 假设我们只想处理前10个字节 Span<byte> dataSpan = new Span<byte>(data, 0, 10); for (int i = 0; i < dataSpan.Length; i++) { // 对每个字节执行操作 dataSpan[i] = (byte)(dataSpan[i] + 1); } Console.WriteLine(System.Text.Encoding.UTF8.GetString(dataSpan)); }

image.png

示例 2:字符串切片

C#
static void Main(string[] args) { SliceString("0123456789abcdefg"); } static void SliceString(string str) { ReadOnlySpan<char> span = str.AsSpan(); ReadOnlySpan<char> slice = span.Slice(start: 5, length: 10); Console.WriteLine(slice.ToString()); }

示例 3:内存复制

C#
static void Main(string[] args) { byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; byte[] data1 = new byte[10]; CopyMemory(data, data1); } static void CopyMemory(byte[] source, byte[] destination) { Span<byte> sourceSpan = source.AsSpan(); Span<byte> destinationSpan = destination.AsSpan(); // 假设 destination 数组足够大 sourceSpan.CopyTo(destinationSpan); }

示例 4:与 Memory 结合使用

C#
static void Main(string[] args) { byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; ProcessLargeData(data); foreach (var item in data) { Console.WriteLine(item.ToString()); } } static void ProcessLargeData(Memory<byte> memory) { // 使用 Memory<T> 的 .Span 属性来获取 Span<T> Span<byte> span = memory.Span; // 现在可以安全地在同步方法中操作内存 for (int i = 0; i < span.Length; i++) { // 对内存执行操作 span[i] = (byte)(span[i] + 1); } }

image.png

Span 的引入显著提高了 C# 程序处理内存数据的能力,尤其对于需要高性能且内存敏感的应用程序而言,它提供了前所未有的控制和优化能力。通过上述示例,我们可以看到 Span 在实际编程中是如何为我们提供更优雅和高效的数据操作方式。

本文作者:技术老小子

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!