You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何无复制无分配且不使用unsafe获取结构体的Span<byte>视图

好的,咱们来聊聊怎么在不使用unsafe关键字的前提下,从单个unmanaged结构体创建Span<byte>视图——要求全程无内存复制、无额外内存分配。

首先,先说说你目前已经用unsafe实现的方案,方便咱们对比参考:

// 使用in参数的版本
public unsafe Span<byte> AsSpan<T>(in T val) where T : unmanaged 
{ 
    void* valPtr = Unsafe.AsPointer(ref Unsafe.AsRef(val)); 
    return new Span<byte>(valPtr, Marshal.SizeOf<T>()); 
} 

// 使用ref参数的简化版本
public unsafe Span<byte> AsSpan<T>(ref T val) where T : unmanaged 
{ 
    void* valPtr = Unsafe.AsPointer(ref val); 
    return new Span<byte>(valPtr, Marshal.SizeOf<T>()); 
}

不过如果是处理数组而不是单个值的话,咱们可以用MemoryMarshal.Cast轻松实现安全的类型转换,完全不需要unsafe:

public Span<byte> AsSpan<T>(Span<T> vals) where T : unmanaged 
{ 
    return MemoryMarshal.Cast<T, byte>(vals); 
}

运行环境说明

你的代码运行环境具体如下:

  • 目标框架:netstandard2.0
  • C#语言版本:7.3
  • 依赖NuGet包:
    • System.Memory 版本4.5.0
    • System.Runtime.CompilerServices.Unsafe 版本4.5.0

对应的项目配置代码如下:

<PropertyGroup> 
  <TargetFramework>netstandard2.0</TargetFramework> 
  <LangVersion>7.3</LangVersion> 
</PropertyGroup> 
<ItemGroup> 
  <PackageReference Include="System.Memory" Version="4.5.0" /> 
  <PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.5.0" /> 
</ItemGroup>

关于内存安全的补充

这里要提一下:C# 7.3引入的where T : unmanaged泛型约束,可以替代普通的struct约束,能有效保证这类内存操作的安全性。官方对该约束的定义是:

where T : unmanaged 类型参数不得为引用类型,且在任何嵌套级别都不得包含引用类型成员。

这样就能避免因为操作包含引用的结构体而导致的内存损坏问题。

内容的提问来源于stack exchange,提问作者zone117x

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:11:09