为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

胡说叔叔 2019-10-06 14:57:34
我正在编写一个原型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中将任何对象完全转换为字节数组?
查看完整描述

3 回答

?
慕田峪9158850

TA贡献1794条经验 获得超7个赞

使用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属性,以便以此成功进行序列化。


查看完整回答
反对 回复 2019-10-06
?
开心每一天1111

TA贡献1836条经验 获得超13个赞

就像其他人之前说过的那样,您可以使用二进制序列化,但是它可能会产生一个额外的字节,或者被反序列化为具有不完全相同数据的对象。另一方面,使用反射非常复杂且非常缓慢。还有另一种解决方案可以将您的对象严格转换为字节,反之亦然-编组:


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]属性。


查看完整回答
反对 回复 2019-10-06
  • 3 回答
  • 0 关注
  • 710 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信