using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Runtime.Serialization;
using System.Globalization;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Converters;
internal class MarketDataObject
public string Id { get; set; }
[ProtoInclude(10, typeof(MarketDataObject))]
internal abstract class LowerStillBaseClass
public string LowerStillBaseClassProperty { get; set; }
internal class MarketDataObject : LowerStillBaseClass
public string Id { get; set; }
internal abstract class LowerStillBaseClass
public string LowerStillBaseClassProperty { get; set; }
internal class MarketDataObject : LowerStillBaseClass
static MarketDataObject()
AddBaseTypeProtoMembers(RuntimeTypeModel.Default);
const int BaseTypeIncrement = 11000;
public static void AddBaseTypeProtoMembers(RuntimeTypeModel runtimeTypeModel)
var myType = runtimeTypeModel[typeof(MarketDataObject)];
var baseType = runtimeTypeModel[typeof(MarketDataObject).BaseType];
if (!baseType.GetSubtypes().Any(s => s.DerivedType == myType))
foreach (var field in baseType.GetFields())
myType.Add(field.FieldNumber + BaseTypeIncrement, field.Name);
public string Id { get; set; }
public static void Test()
var test1data = Test(new V1.MarketDataObject { Id = "101", });
var test2data = Test(new V2.MarketDataObject { Id = "101", LowerStillBaseClassProperty = "lower still" });
var test3data = Test(new V3.MarketDataObject { Id = "101", LowerStillBaseClassProperty = "lower still" });
TestRoundTrip<V1.MarketDataObject, V3.MarketDataObject>(new V1.MarketDataObject { Id = "101", });
TestRoundTrip<V1.MarketDataObject, V2.MarketDataObject>(new V1.MarketDataObject { Id = "101", });
static byte[] TestRoundTrip<TIn, TOut>(TIn test1)
Console.WriteLine("Trying to roundtrip an object of type {0} to type {1} and back...", typeof(TIn), typeof(TOut));
var token1 = JToken.FromObject(test1);
Console.WriteLine(token1.ToString(Newtonsoft.Json.Formatting.None));
var data = test1.SerializeToByteArray();
var temp = data.DeserializeFromByteArray<TOut>();
var tempToken = JToken.FromObject(temp);
Console.WriteLine(tempToken.ToString(Newtonsoft.Json.Formatting.None));
var data2 = temp.SerializeToByteArray();
var test1back = data2.DeserializeFromByteArray<TIn>();
var token1back = JToken.FromObject(test1back);
Console.WriteLine(token1back.ToString(Newtonsoft.Json.Formatting.None));
if (!JToken.DeepEquals(token1back, token1))
throw new InvalidOperationException("!JToken.DeepEquals(token1back, token1)");
Console.WriteLine("successfully roundtrip of an object of type {0} to type {1}.\n\n", typeof(TIn), typeof(TOut));
Console.WriteLine("FAILED trying to roundtrip an object of type {0} as type {1}, exception:", typeof(V1.MarketDataObject), typeof(V3.MarketDataObject));
static byte[] Test<T>(T test1)
Console.WriteLine("Testing serialization of {0}.", typeof(T));
Console.WriteLine("Dumping schema:", typeof(T));
Console.WriteLine(RuntimeTypeModel.Default.GetSchema(typeof(T)));
var token1 = JToken.FromObject(test1);
Console.WriteLine("Initial object: " + token1.ToString(Newtonsoft.Json.Formatting.None));
var data = test1.SerializeToByteArray();
var test1back = data.DeserializeFromByteArray<T>();
var token1back = JToken.FromObject(test1back);
Console.WriteLine("Deserialized object: " + token1back.ToString(Newtonsoft.Json.Formatting.None));
if (!JToken.DeepEquals(token1back, token1))
throw new InvalidOperationException("!JToken.DeepEquals(token1back, token1)");
Console.WriteLine("Successful serialization of {0}.\n\n", typeof(T));
public static class SerializerExtensions
public static byte[] SerializeToByteArray<T>(this T instance)
using (var ms = new MemoryStream())
Serializer.Serialize(ms, instance);
public static T DeserializeFromByteArray<T>(this byte [] data)
using (var ms = new MemoryStream(data))
return Serializer.Deserialize<T>(ms);
public static void Main()
Console.WriteLine("protobuf-net version: " + typeof(ProtoBuf.Serializer).Assembly.FullName);
ProtoBuf.Meta.RuntimeTypeModel.Default.AutoCompile = false;