如何在C#中将值类型转换为字节[]?

如何在C#中将值类型转换为字节[]?,c#,arrays,C#,Arrays,我想做类似的事情: byte[] byteArray; enum commands : byte {one, two}; commands content = one; byteArray = (byte*)&content; 是的,现在是一个字节,但是我想在将来改变它吗?如何使byteArray包含内容?(我不想复制它)。您可以使用该方法执行此操作。该类可能就是您要查找的。例如: int input = 123; byte[] output = BitConverter.GetByt

我想做类似的事情:

byte[] byteArray;
enum commands : byte {one, two};
commands content = one;
byteArray = (byte*)&content;

是的,现在是一个字节,但是我想在将来改变它吗?如何使byteArray包含内容?(我不想复制它)。

您可以使用该方法执行此操作。

该类可能就是您要查找的。例如:

int input = 123;
byte[] output = BitConverter.GetBytes(input);
如果已知枚举是Int32派生类型,则可以首先强制转换其值:

BitConverter.GetBytes((int)commands.one);

要将任何值类型(不仅仅是基元类型)转换为字节数组,反之亦然,请执行以下操作:

    public T FromByteArray<T>(byte[] rawValue)
    {
        GCHandle handle = GCHandle.Alloc(rawValue, GCHandleType.Pinned);
        T structure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
        handle.Free();
        return structure;
    }

    public byte[] ToByteArray(object value, int maxLength)
    {
        int rawsize = Marshal.SizeOf(value);
        byte[] rawdata = new byte[rawsize];
        GCHandle handle =
            GCHandle.Alloc(rawdata,
            GCHandleType.Pinned);
        Marshal.StructureToPtr(value,
            handle.AddrOfPinnedObject(),
            false);
        handle.Free();
        if (maxLength < rawdata.Length) {
            byte[] temp = new byte[maxLength];
            Array.Copy(rawdata, temp, maxLength);
            return temp;
        } else {
            return rawdata;
        }
    }
public T FromByteArray(字节[]rawValue)
{
GCHandle handle=GCHandle.Alloc(原始值,GCHandleType.pinted);
T structure=(T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(),typeof(T));
handle.Free();
回报结构;
}
公共字节[]ToByteArray(对象值,int maxLength)
{
int rawsize=Marshal.SizeOf(值);
字节[]rawdata=新字节[rawsize];
手柄=
GCHandle.Alloc(原始数据,
GCHandleType.pinted);
Marshal.StructureToPtr(值,
handle.AddRofPindedObject(),
假);
handle.Free();
if(最大长度
对于任何对其工作原理感兴趣而不使用
位转换器的人,您可以这样做:

// Convert double to byte[]
public unsafe byte[] pack(double d) {
    byte[] packed = new byte[8]; // There are 8 bytes in a double
    void* ptr = &d; // Get a reference to the memory containing the double
    for (int i = 0; i < 8; i++) { // Each one of the 8 bytes needs to be added to the byte array
        packed[i] = (byte)(*(UInt64 *)ptr >> (8 * i)); // Bit shift so that each chunk of 8 bits (1 byte) is cast as a byte and added to array 
    }
    return packed;
}

// Convert byte[] to double
public unsafe double unpackDouble(byte[] data) {
    double unpacked = 0.0; // Prepare a chunk of memory ready for the double
    void* ptr = &unpacked; // Reference the double memory
    for (int i = 0; i < data.Length; i++) {
        *(UInt64 *)ptr |= ((UInt64)data[i] << (8 * i)); // Get the bits into the right place and OR into the double
    }
    return unpacked;
}
//将双精度转换为字节[]
公共不安全字节[]包(双d){
byte[]packed=新字节[8];//一个双字节中有8个字节
void*ptr=&d;//获取对包含双精度
对于(inti=0;i<8;i++){//8个字节中的每一个都需要添加到字节数组中
压缩[i]=(字节)(*(UInt64*)ptr>>(8*i));//位移位,以便将8位(1字节)的每个块转换为一个字节并添加到数组中
}
退货包装;
}
//将字节[]转换为双字节
公共不安全双字节(字节[]数据){
double unpacket=0.0;//准备一块内存,以便进行双精度压缩
void*ptr=&unpacket;//引用双内存
for(int i=0;i*(UInt64*)ptr |=((UInt64)数据[i]如果基元类型还不够,请参阅我的答案,了解如何转换任何值类型。非常好,这正是我一直在搜索的,这应该是正确的答案,因为BitConverter不适用于所有类型。但是,在所有实现它的平台上,BitConverter在所有支持的类型中都是一致的。应该注意的是此方法的“返回”不可跨不同平台移植,甚至可能无法跨.NET framework的不同版本工作,因此这不适用于序列化,除非您能够保证.NET framework版本在序列化和反序列化端是相同的。这可能会使应用程序的升级变得非常困难。@MikeMarynowski:刚刚看到你的评论。我不知道你的意思。这段代码不涉及二进制序列化,它使用封送,封送的目的是准确地获取你请求调用P/Invoke或COM API的字节。使用此方法,你可以准确地获取你在结构中定义的字节(使用StructLayoutAttribute等)不管是.NET版本还是平台。@ OregonGhost,SLek解决方案,但是我想知道一个结构是否没有用StructLayoutAttributes定义,什么决定了输出字节的顺序?它不能从.NET版本转换到版本吗?也许这就是迈克的意思。@ CRG:也许。但是我甚至从来没有考虑过使用结构来进行编组。未使用StructLayoutAttribute正确声明。使用基本结构(即BitConverter无论如何都支持的类型),这一点也不会改变。无论如何,BitConverter在不同平台之间并不一致,它取决于系统的endianness,就像编组一样。这就是为什么您通常为处理endianness的整数字段添加属性,而实际字段已经按网络顺序排列。