Reputation: 884
I am experimenting with using protobuf-net for an upcoming project but I am having a hard time figuring out how to serialize lists of a class. I have created a dotnet fiddle to test out some basic scenarios and everything works until I create a simple class and add a list of that class to another class to be serialized. I create an instance of my class and print it to show all the values, then serialize, deserialize and print again to show that all the data made it through the process but my list keeps coming back empty. Anyone know whats going on here?
using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Collections.Generic;
using ProtoBuf;
using ProtoBuf.Meta;
public class Program
{
public static void Main()
{
var item = new MyClass();
var listItem1 = new ComplexList();
listItem1.pubField = "first one";
var listItem2 = new ComplexList();
listItem2.pubField = "second one";
item.ComplexList.Add(listItem1);
item.ComplexList.Add(listItem2);
item.Print();
Console.WriteLine();
Console.WriteLine();
var serialized = ProtoObjectToByteArray(item);
var deserialized = ProtoByteArrayToObject<MyClass>(serialized);
deserialized.Print();
}
public static byte[] ProtoObjectToByteArray(object obj)
{
if(obj == null)
return null;
using (MemoryStream ms = new MemoryStream())
{
Serializer.Serialize(ms, obj);
return ms.ToArray();
}
}
public static T ProtoByteArrayToObject<T>(byte[] arrBytes)
{
if(arrBytes == null)
return default(T);
using (MemoryStream ms = new MemoryStream(arrBytes))
{
return Serializer.Deserialize<T>(ms);
}
}
}
[Serializable, ProtoContract]
public class ComplexList {
public string pubField;
public ComplexList(){}
}
[Serializable, ProtoContract]
public class MyClass {
public List<ComplexList> ComplexList { get; set; }
public MyClass(){
ComplexList = new List<ComplexList>();
}
public void Print(){
foreach(var x in ComplexList){
Console.WriteLine(x.pubField);
}
}
}
Updated as requested https://dotnetfiddle.net/vnfMWh
Upvotes: 2
Views: 180
Reputation: 1062780
Protobuf-net wants you to annotate your type:
[Serializable, ProtoContract]
public class ComplexList {
[ProtoMember(1)]
public string pubField;
public ComplexList(){}
}
[Serializable, ProtoContract]
public class MyClass {
[ProtoMember(1)]
public List<ComplexList> ComplexList { get; set; }
public MyClass(){
ComplexList = new List<ComplexList>();
}
public void Print(){
foreach(var x in ComplexList){
Console.WriteLine(x.pubField);
}
}
}
Fields in protobuf are given numeric identifiers and it wants a reliable way of knowing which field is which number.
Note that you don't need [Serializable]
for protobuf-net.
Upvotes: 3