【发布时间】:2012-04-26 12:12:37
【问题描述】:
我检查过,但似乎无法看到如何将一个类直接序列化为一个字节数组,然后使用 Marc Gravell 的 protobuf-net 实现从一个字节数组反序列化。
编辑:我更改了问题并提供了代码,因为如何序列化为 byte[] 而无需通过流的原始问题无疑是微不足道的。我很抱歉。
更新的问题:有没有办法不必处理泛型,而是在通过构造函数时通过反射推断属性“MessageBody”的类型?我假设我不能序列化对象类型,对吗?当前的解决方案看起来非常繁琐,因为每次实例化一个新消息时,我都需要传入 MessageBody 的类型。有没有更时尚的解决方案?
我想出了以下内容:
class Program
{
static void Main(string[] args)
{
Message<string> msg = new Message<string>("Producer", "Consumer", "Test Message");
byte[] byteArray = msg.Serialize();
Message<string> message = Message<string>.Deserialize(byteArray);
Console.WriteLine("Output");
Console.WriteLine(message.From);
Console.WriteLine(message.To);
Console.WriteLine(message.MessageBody);
Console.ReadLine();
}
}
[ProtoContract]
public class Message<T>
{
[ProtoMember(1)]
public string From { get; private set; }
[ProtoMember(2)]
public string To { get; private set; }
[ProtoMember(3)]
public T MessageBody { get; private set; }
public Message()
{
}
public Message(string from, string to, T messageBody)
{
this.From = from;
this.To = to;
this.MessageBody = messageBody;
}
public byte[] Serialize()
{
byte[] msgOut;
using (var stream = new MemoryStream())
{
Serializer.Serialize(stream, this);
msgOut = stream.GetBuffer();
}
return msgOut;
}
public static Message<T> Deserialize(byte[] message)
{
Message<T> msgOut;
using (var stream = new MemoryStream(message))
{
msgOut = Serializer.Deserialize<Message<T>>(stream);
}
return msgOut;
}
}
我喜欢的是这样的:
Message newMsg = new Message("Producer", "Consumer", Foo); byte[] byteArray = newMsg.Serialize();
和 Message msg = Message.Deserialize(byteArray);
(其中 Deserialize 是一个静态方法,它总是反序列化成 Message 类型的对象,只需要知道将消息体反序列化成什么类型)。
【问题讨论】:
-
Protobuf.net 不是开源的吗?
-
是的,但我不想调整源代码,因为我喜欢跟上新版本而不必进行后续调整,因为库只是一个非常小的组件,作为更大项目的一部分。
-
一个
MemoryStream只是变相的字节数组,使用它有什么问题? -
我知道,但想知道是否存在我可能忽略的函数重载
-
如果你只是想序列化类,那么只需在类上方使用[Serializable]即可。它工作得很好,但是它不能与 ProtoContract 一起使用。仅使用(选择)ProtoContract 或 Serializable 功能。
标签: c# serialization bytearray protocol-buffers protobuf-net