在C#中无堆内存分配地将数值类型转换为字节
无堆分配的数值类型转多字节实现方案
针对.NET Framework 4.8(C# 7.3)环境,以下几种方法可以实现数值类型转多字节且避免堆内存分配:
方法一:位运算(仅适用于整数类型)
通过位掩码和移位操作直接提取每个字节,完全不需要堆内存,代码直观且无需特殊编译配置。
short转双字节示例
public static void GetBytes(short input, out byte byte0, out byte byte1) { byte0 = (byte)(input & 0xFF); byte1 = (byte)((input >> 8) & 0xFF); }
int转四字节示例
public static void GetBytes(int input, out byte byte0, out byte byte1, out byte byte2, out byte byte3) { byte0 = (byte)(input & 0xFF); byte1 = (byte)((input >> 8) & 0xFF); byte2 = (byte)((input >> 16) & 0xFF); byte3 = (byte)((input >> 24) & 0xFF); }
注:上述代码采用小端字节序,与
BitConverter.GetBytes默认行为一致;若需大端序,调整移位顺序即可。
方法二:显式布局结构体(Union,支持所有数值类型)
利用[StructLayout(LayoutKind.Explicit)]定义重叠字段的结构体,赋值数值后直接读取对应字节,结构体作为值类型在栈上分配,无堆开销。
通用转换结构体及示例
using System.Runtime.InteropServices; [StructLayout(LayoutKind.Explicit)] public struct NumericByteUnion { [FieldOffset(0)] public short ShortValue; [FieldOffset(0)] public int IntValue; [FieldOffset(0)] public float FloatValue; [FieldOffset(0)] public byte Byte0; [FieldOffset(1)] public byte Byte1; [FieldOffset(2)] public byte Byte2; [FieldOffset(3)] public byte Byte3; } // short转字节 public static void GetBytes(short input, out byte byte0, out byte byte1) { var union = new NumericByteUnion { ShortValue = input }; byte0 = union.Byte0; byte1 = union.Byte1; } // float转字节 public static void GetBytes(float input, out byte byte0, out byte byte1, out byte byte2, out byte byte3) { var union = new NumericByteUnion { FloatValue = input }; byte0 = union.Byte0; byte1 = union.Byte1; byte2 = union.Byte2; byte3 = union.Byte3; }
方法三:不安全指针操作(支持所有数值类型)
直接操作内存地址读取字节,性能最优,但需要在项目编译选项中开启“允许不安全代码”。
short转字节示例
public static unsafe void GetBytes(short input, out byte byte0, out byte byte1) { fixed (short* ptr = &input) { byte* bytePtr = (byte*)ptr; byte0 = *bytePtr; byte1 = *(bytePtr + 1); } }
float转字节示例
public static unsafe void GetBytes(float input, out byte byte0, out byte byte1, out byte byte2, out byte byte3) { fixed (float* ptr = &input) { byte* bytePtr = (byte*)ptr; byte0 = *bytePtr; byte1 = *(bytePtr + 1); byte2 = *(bytePtr + 2); byte3 = *(bytePtr + 3); } }
方案对比
- 位运算:仅支持整数类型,代码简洁,无需特殊配置,性能优异。
- 显式布局结构体:支持所有数值类型,可读性好,无需不安全代码,性能接近位运算。
- 不安全指针:性能最优,支持所有类型,但需开启不安全代码,可读性稍弱。
内容的提问来源于stack exchange,提问作者mike
相关产品推荐
相关产品推荐

