Help is needed with the most trivial example of protobuf-net 3

Given:

public class E
{
  public object Y { get; set; }
}

I am trying to execute the following code:

var m = RuntimeTypeModel.Default;
m.Add(typeof(E), false).Add("Y");
// m.Add(typeof(object), false).AddSubType(1, typeof(int));

var e = new E { Y = 5 };
using (var ms = new MemoryStream())
{
  m.Serialize(ms, e);
  ms.Position = 0;
  var e2 = (E)m.Deserialize(ms, null, typeof(E));
  Debug.Assert(e.Y.Equals(e2.Y));
}

Failure:

System.InvalidOperationException occurred
  Message=No serializer defined for type: System.Object
  Source=protobuf-net
  StackTrace:
       at ProtoBuf.Meta.ValueMember.GetCoreSerializer(Type type, WireType& defaultWireType, Boolean asReference, Boolean dynamicType) in C:\Work\protobuf-net-v2\protobuf-net\Meta\ValueMember.cs:line 398
  InnerException: 

So, I will uncomment the third line, but then I get:

System.ArgumentException occurred
  Message=Not valid for primitive types
Parameter name: type
  Source=protobuf-net
  ParamName=type
  StackTrace:
       at ProtoBuf.Meta.MetaType..ctor(RuntimeTypeModel model, Type type) in C:\Work\protobuf-net-v2\protobuf-net\Meta\MetaType.cs:line 166
  InnerException: 

Therefore, the question arises: how do I (de) serialize a property of an object containing an instance of an instance type primitive ?

Note that the same approach works with a non-primitive value type, such as DateTime (of course, I had to use a surrogate).

EDIT

If I comment on the primitiveness check in the method ProtoBuf.Meta.MetaType.MetaType, the following code works correctly:

static void Main()
{
  var m = RuntimeTypeModel.Default;
  m.Add(typeof(E), false).Add("Y");
  m.Add(typeof(object), false).AddSubType(1, typeof(int));
  m.Add(typeof(IntSurrogate), false).Add("Value");
  m.Add(typeof(int), false).SetSurrogate(typeof(IntSurrogate));

  var e = new E { Y = 5 };
  using (var ms = new MemoryStream())
  {
    m.Serialize(ms, e);
    ms.Position = 0;
    var e2 = (E)m.Deserialize(ms, null, typeof(E));
    Debug.Assert(e.Y.Equals(e2.Y));
  }
}

internal class IntSurrogate
{
  public static implicit operator int(IntSurrogate surrogate)
  {
    return surrogate.Value;
  }
  public static implicit operator IntSurrogate(int v)
  {
    return new IntSurrogate { Value = v };
  }

  internal int Value { get; set; }
}

Of course, I would like it to work unnecessarily IntSurrogate.

+3
source share

All Articles