Дано:
public class E
{
public object Y { get; set; }
}
Я пытаюсь следующий код:
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));
}
Не удается с:
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:
Итак, я раскомментирую третью строку, но затем получаю:
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:
Следовательно, возникает вопрос - как (де) сериализовать свойство объекта, содержащее примитив экземпляр типа упакованного значения?
Обратите внимание, что тот же подход работает с не примитивным типом значения, таким как DateTime (конечно, я должен был использовать суррогат).
EDIT
Если я прокомментирую проверку примитивности в методе ProtoBuf.Meta.MetaType.MetaType
, то следующий код будет работать правильно:
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; }
}
Конечно, я бы хотел, чтобы это работало без необходимости IntSurrogate
.