将任何对象转换为字节[]

我正在编写一个原型TCP连接,但在均匀化要发送的数据时遇到了一些麻烦。


目前,我只发送字符串,但是将来我们希望能够发送任何对象。


此刻的代码非常简单,因为我认为所有内容都可以转换为字节数组:


void SendData(object headerObject, object bodyObject)

{

  byte[] header = (byte[])headerObject;  //strings at runtime, 

  byte[] body = (byte[])bodyObject;      //invalid cast exception


  // Unable to cast object of type 'System.String' to type 'System.Byte[]'.

  ...

}

这当然很容易解决


if( state.headerObject is System.String ){...}

问题是,如果我这样做,我需要在运行时检查无法转换为byte []的每种类型的对象。


由于我不知道每个对象在运行时都不能转换为byte [],因此这实际上不是一个选择。


如何在C#.NET 4.0中将任何对象完全转换为字节数组?


胡说叔叔
浏览 711回答 3
3回答

慕田峪9158850

使用BinaryFormatter:byte[] ObjectToByteArray(object obj){    if(obj == null)        return null;    BinaryFormatter bf = new BinaryFormatter();    using (MemoryStream ms = new MemoryStream())    {        bf.Serialize(ms, obj);        return ms.ToArray();    }}请注意,obj其中的任何属性/字段obj(及其所有属性/字段都将如此)都需要标记为该Serializable属性,以便以此成功进行序列化。

开心每一天1111

就像其他人之前说过的那样,您可以使用二进制序列化,但是它可能会产生一个额外的字节,或者被反序列化为具有不完全相同数据的对象。另一方面,使用反射非常复杂且非常缓慢。还有另一种解决方案可以将您的对象严格转换为字节,反之亦然-编组:var size = Marshal.SizeOf(your_object);// Both managed and unmanaged buffers required.var bytes = new byte[size];var ptr = Marshal.AllocHGlobal(size);// Copy object byte-to-byte to unmanaged memory.Marshal.StructureToPtr(your_object, ptr, false);// Copy data from unmanaged memory to managed buffer.Marshal.Copy(ptr, bytes, 0, size);// Release unmanaged memory.Marshal.FreeHGlobal(ptr);并将字节转换为对象:var bytes = new byte[size];var ptr = Marshal.AllocHGlobal(size);Marshal.Copy(bytes, 0, ptr, size);var your_object = (YourType)Marshal.PtrToStructure(ptr, typeof(YourType));Marshal.FreeHGlobal(ptr);与您自己的序列化字段(逐字段复制)相比,将这种方法用于小型对象和结构要慢得多,并且在某种程度上不安全(由于从/到非托管内存的双重复制),但这是将对象严格转换为byte []而不实现序列化的最简单方法并且没有[Serializable]属性。
打开App,查看更多内容
随时随地看视频慕课网APP