Thanks for the great library Marc and for all the answers on SO.
I'm using protobuf-net r480.zip on .NET 4.0.zip from http://code.google.com/p/protobuf-net/downloads/list. Is this the latest stable release?
I'm having trouble serializing a custom collection.
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> { }
Thanks for the anser Marc, removing the Proto attributes works great if just using a list. Unfortunately, the actual code is more complex - the derived collection contains other values (in the real code the template parameter in of type Entity instead of int and the member in the collection is a reference to the parent of the elements in the collection). Here is a better representation.
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;
}