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");
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.