如何将数值(例如
float
、short
、int
...)转换为多个 byte
值,而无需像 System.BitConverter.GetBytes
那样在堆上为数组分配内存?
类似这样的:
public static void GetBytes(short input, out byte byte0, out byte byte1)
{
//demo code, just to show which results I need
var bytes = System.BitConverter.GetBytes(input);
byte0 = bytes[0];
byte1 = bytes[1];
}
注意:我仅限于 .NET Framework 4.8,因此(我认为)C# 7.3。
只需施放并移动?
public static void GetBytes(short input, out byte byte0, out byte byte1)
{
byte0 = (byte)input;
byte1 = (byte)(input >> 8);
}
请注意,您可以简单地反转不同字节顺序的顺序。
请注意,如果您使用“已检查”上下文,则还需要屏蔽:
public static void GetBytes(short input, out byte byte0, out byte byte1)
{
byte0 = (byte)(input & 0xFF);
byte1 = (byte)((input >> 8) & 0xFF);
}
(在未经检查的上下文中,转换为
byte
本身就足够了 - 额外的位被丢弃)
如果允许使用不安全代码,那么对于非整数值类型(例如
float
、double
和 decimal
),最快的方法是使用指针。
例如,对于
double
:
double x = 123.456;
unsafe
{
byte* p = (byte*) &x;
// Doubles have 8 bytes.
byte b0 = *p++;
byte b1 = *p++;
byte b2 = *p++;
byte b3 = *p++;
byte b4 = *p++;
byte b5 = *p++;
byte b6 = *p++;
byte b7 = *p;
}
您应该能够看到如何针对其他类型修改它。
对于诸如
short
、int
和 long
之类的整数类型,您可以使用 Mark Gravell 的其他答案中给出的方法 - 但您也可以对整数类型使用上面的指针方法。
重要提示:使用指针方法时,字节序非常重要!字节分配的顺序就是它们在内存中存储的顺序,这可能因处理器架构而异。
您可以在此处放置任何 ValueType。
public static Span<byte> AsSpan<T>(ref T val) where T : unmanaged
{
Span<T> valSpan = MemoryMarshal.CreateSpan(ref val, 1);
return MemoryMarshal.Cast<T, byte>(valSpan);
}
然后你可以反过来做。
public static T Convert<T>(ref Span<byte> span) where T : unmanaged
{
return MemoryMarshal.Read<T>(span);
}
用途:
int i = 123;
float f = 0.000_1f;
Span<byte> spanInt = AsSpan(ref i);
Span<byte> spanFloat =AsSpan (ref f);
int i2 = Convert<int>(ref spanInt);
float f2 = Convert<float>(ref spanFloat);
Console.Write($"{i2} {f2}");