我有一个List<object>
,其中包含不同类型的对象,如整数,字符串和自定义类型。所有自定义类型都是protobuf调整。
我现在要做的是使用protobuf.net序列化/反序列化此列表。到目前为止,我怀疑我必须明确地声明每个类型,遗憾的是这些混合列表结构是不可能的。因为二元形成器没有问题做这些事情我希望我错过了一些东西,你可以帮助我。
所以我的问题是如何处理protobuf.net中的对象。
答案 0 :(得分:11)
(披露:我是protobuf-net的作者)
BinaryFormatter
是基于元数据的序列化程序;即它发送有关序列化的每个对象的.NET类型信息。 protobuf-net是一个基于合同的序列化器(二进制等效于XmlSerializer
/ DataContractSerializer
,它也会拒绝这个)。
目前没有传输任意对象的机制,因为另一端无法知道你发送的内容;但是,如果您要发送已知 对象类型,则可能有选项。管道中还有工作允许运行时可扩展的模式(而不仅仅是在构建时修复的属性) - 但这远非完整。
这不是理想的,但是它有效...当我完成支持运行时模式的工作时应该会更容易:
using System;
using System.Collections.Generic;
using ProtoBuf;
[ProtoContract]
[ProtoInclude(10, typeof(DataItem<int>))]
[ProtoInclude(11, typeof(DataItem<string>))]
[ProtoInclude(12, typeof(DataItem<DateTime>))]
[ProtoInclude(13, typeof(DataItem<Foo>))]
abstract class DataItem {
public static DataItem<T> Create<T>(T value) {
return new DataItem<T>(value);
}
public object Value {
get { return ValueImpl; }
set { ValueImpl = value; }
}
protected abstract object ValueImpl {get;set;}
protected DataItem() { }
}
[ProtoContract]
sealed class DataItem<T> : DataItem {
public DataItem() { }
public DataItem(T value) { Value = value; }
[ProtoMember(1)]
public new T Value { get; set; }
protected override object ValueImpl {
get { return Value; }
set { Value = (T)value; }
}
}
[ProtoContract]
public class Foo {
[ProtoMember(1)]
public string Bar { get; set; }
public override string ToString() {
return "Foo with Bar=" + Bar;
}
}
static class Program {
static void Main() {
var items = new List<DataItem>();
items.Add(DataItem.Create(12345));
items.Add(DataItem.Create(DateTime.Today));
items.Add(DataItem.Create("abcde"));
items.Add(DataItem.Create(new Foo { Bar = "Marc" }));
items.Add(DataItem.Create(67890));
// serialize and deserialize
var clone = Serializer.DeepClone(items);
foreach (DataItem item in clone) {
Console.WriteLine(item.Value);
}
}
}
答案 1 :(得分:0)
List<YourClass> list;
ProtoBuf.Serializer.Deserialize<List<YourClass>>(filestream);