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

C#如何从ushort[]的任意位置获取byte[]且不复制数据

在C#中从ushort[]任意位置获取无复制的byte[]

我有一个长度为7的ushort[]示例:

var ushorts = new ushort[7] {1, 2, 3, 4, 5, 6, 7};

它在内存中占用14个连续字节:

01 00 02 00 03 00 04 00 05 00 06 00 07 00

需要从这14个字节的中间任意位置获取一个byte[],且不复制数据。类似C++中通过指针重定向实现的无复制操作:

#include <iostream>

typedef unsigned short ushort;
typedef unsigned char byte;

int main() {
    ushort* ushorts = new ushort[7] {1, 2, 3, 4, 5, 6, 7};
    byte* bytes = reinterpret_cast<byte*>(&(ushorts[2]));

    for (int i = 0; i < 8; i++) {
        std::cout << (int)bytes[i] << ' ';
    }
    // stdout: 3 0 4 0 5 0 6 0

    std::cout << std::endl;
    delete ushorts;
    return 0;
}

方案1:使用Span或Memory(推荐,无unsafe代码)

在.NET Core 2.1+、.NET 5+或.NET Standard 2.1+环境下,可借助Span<T>和Memory<T>实现无复制的内存视图操作,无需unsafe权限:

var ushorts = new ushort[7] {1, 2, 3, 4, 5, 6, 7};

// 将ushort[]直接映射为字节视图,无数据复制
Span<byte> allBytes = MemoryMarshal.AsBytes(ushorts.AsSpan());

// 从第4个字节(对应ushorts[2]的起始位置)截取8个字节的视图
Span<byte> targetBytes = allBytes.Slice(start: 4, length: 8);

// 若需用于异步场景或保存持久引用,可转为Memory<byte>
Memory<byte> targetMemory = targetBytes;

// 验证输出
foreach (byte b in targetBytes)
{
    Console.Write($"{b} ");
}
// 输出:3 0 4 0 5 0 6 0
  • 核心逻辑:MemoryMarshal.AsBytes直接把原数组的内存区域映射为字节视图,Slice仅创建指向原内存片段的新视图,全程无数据复制。
  • 注意:原生byte[]是独立托管内存块,无法直接让它指向另一个数组的内存片段。如果业务场景可以接受用Span<byte>/Memory<byte>替代byte[],这是最优解;若必须要byte[],则只能通过ToArray()复制数据,但这不符合无复制要求。

方案2:使用unsafe代码(模拟C++指针逻辑)

如果是.NET Framework环境或必须用指针操作,可开启unsafe代码实现:

unsafe
{
    var ushorts = new ushort[7] {1, 2, 3, 4, 5, 6, 7};
    
    fixed (ushort* ushortPtr = &ushorts[2])
    {
        byte* bytePtr = (byte*)ushortPtr;
        
        // 直接操作指针访问原内存
        for (int i = 0; i < 8; i++)
        {
            Console.Write($"{bytePtr[i]} ");
        }
        // 输出:3 0 4 0 5 0 6 0
    }
}
  • 核心逻辑:fixed关键字固定数组内存防止GC移动,通过指针类型转换直接访问原数组的字节区域,无数据复制。
  • 注意:需在项目设置中开启“允许不安全代码”选项才能编译运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 05:07:45