最简单的 protobuf-net 示例 3 需要帮助
鉴于:
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(当然,我必须使用代理)。
编辑
如果我在方法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
。
Given:
public class E
{
public object Y { get; set; }
}
I am trying 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));
}
It fails with:
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 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:
Hence, the question is - how do I (de)serialize an object property containing a primitive boxed value type instance?
Note, that the same approach does work with a non primitive value type, like DateTime (of course, I had to use a surrogate).
EDIT
If I comment the primitivity check in method ProtoBuf.Meta.MetaType.MetaType
, then 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 to see it work without the need for IntSurrogate
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论