感谢伟大的图书馆 Marc 以及关于 SO 的所有答案。
我在http://code.google.com/p/protobuf-net/downloads/list的 .NET 4.0.zip 上使用 protobuf-net r480.zip 。这是最新的稳定版本吗?
我在序列化自定义集合时遇到问题。
public static void TestSerialization() {
using (var stream = new MemoryStream()) {
var b1 = new B1 { 1 };
// Throws System.ArgumentException: Repeated data (a list, collection, etc) has inbuilt behaviour and cannot be subclassed
Serializer.Serialize(stream, b1);
}
using (var stream = new MemoryStream()) {
var b2 = new B2 { 2 };
Serializer.Serialize(stream, b2);
stream.Position = 0;
var b2Deserialized = Serializer.Deserialize<B2>(stream);
// This fails because b2Deserialized.Count is 0.
Assert.AreEqual(1, b2Deserialized.Count);
}
using (var stream = new MemoryStream()) {
RuntimeTypeModel.Default[typeof(A2<int>)].AddSubType(1000, typeof(B2));
var b2 = new B2 { 2 };
// Throws System.ArgumentException: Repeated data (a list, collection, etc) has inbuilt behaviour and cannot be subclassed
Serializer.Serialize(stream, b2);
}
}
[ProtoContract]
[ProtoInclude(1000, typeof(B1))]
public class A1<T> : List<T> { }
[ProtoContract]
public class B1 : A1<int> { }
[ProtoContract]
public class A2<T> : List<T> { }
[ProtoContract]
public class B2 : A2<int> { }
感谢 Anser Marc,如果仅使用列表,删除 Proto 属性效果很好。不幸的是,实际代码更复杂 - 派生集合包含其他值(在实际代码中,模板参数的类型为 Entity 而不是 int,并且集合中的成员是对集合中元素的父级的引用)。这是一个更好的表示。
public static void TestSerialization() {
using (var stream = new MemoryStream()) {
var b = new B { 23 };
b.SomeValue = "abc";
Serializer.Serialize(stream, b);
stream.Position = 0;
var deserialized = Serializer.Deserialize<B>(stream);
Assert.AreEqual(1, deserialized.Count);
Assert.AreEqual(b[0], deserialized[0]);
// This fails because deserialized.SomeValue == null
Assert.AreEqual(b.SomeValue, deserialized.SomeValue);
}
}
public class A<T> : List<T> { }
public class B : A<int>
{
[ProtoMember(1)]
public string SomeValue;
}