问题描述
我正在尝试使用 protobuf-net 序列化一些对象,但不幸的是他们自由地使用 DateTimeOffset
,protobuf-net 尚不支持.这导致了很多:
I'm trying to serialize some objects with protobuf-net, but unfortunately they make liberal use of DateTimeOffset
, which is not yet supported by protobuf-net. This leads to lots of:
没有为类型定义序列化器:System.DateTimeOffset
我可以为未知类型定义自己的序列化例程吗?(同样的问题之前被问过,但他的问题已经解决了.)
Can I define my own serialization routine for unknown types? (The same question was asked earlier, but his problem was worked around.)
我使用的是最新的 protobuf-net beta,v2.0.0.431,在 .NET 4 下(如果重要的话).我也在使用运行时定义,所以我无法声明性地指定如何处理某些属性.
I'm using the latest protobuf-net beta, v2.0.0.431, under .NET 4 if it matters. I'm also using runtime definitions, so I have no way to declaratively specify how certain properties are to be handled.
推荐答案
有两种方法可以解决未知常见"类型的问题;第一种是使用 shim 属性,例如将值表示为类似内容的属性(例如 string
或 long
):
There are two ways of approaching the issue of unknown "common" types; the first is to use a shim property, for example a property that represents the value as something similar (a string
or long
for example):
[ProtoMember(8)]
public string Foo {
get { ... read from the other member ... }
set { ... assign the other member ... }
}
另一种方法是 surrogate,它是自动替换的第二个 protobuf 合约.使用代理的要求是:
The other approach is a surrogate, which is a second protobuf contract that is automatically substituted. The requirements to use a surrogate are:
- 这两种类型(例如,
DateTimeOffset
和DateTimeOffsetSurrogate
)之间必须有一个已定义的转换运算符(隐式或显式) - 然后使用
SetSurrogate(surrogateType)
来训练protobuf-net,例如RuntimeTypeModel.Default.Add(typeof(DateTimeOffset), false).SetSurrogate(typeof(DateTimeOffsetSurrogate));
- there must be a defined conversion operator (implicit or explict) between the two types (for example,
DateTimeOffset
andDateTimeOffsetSurrogate
) - you then use
SetSurrogate(surrogateType)
to educate protobuf-net, for exampleRuntimeTypeModel.Default.Add(typeof(DateTimeOffset), false).SetSurrogate(typeof(DateTimeOffsetSurrogate));
shim 属性更简单,但需要每个成员重复.代理会自动应用于模型中该类型的所有实例.然后代理遵循标准的 protobuf-net 规则,因此您将指示要序列化的成员等.
the shim property is simpler, but requires repeat per-member. The surrogate is applied automatically to all instances of the type within the model. The surrogate then follows standard protobuf-net rules, so you would indicate which members to serialize, etc.
添加代码示例
using System;
using ProtoBuf;
[ProtoContract]
public class DateTimeOffsetSurrogate
{
[ProtoMember(1)]
public string DateTimeString { get; set; }
public static implicit operator DateTimeOffsetSurrogate(DateTimeOffset value)
{
return new DateTimeOffsetSurrogate {DateTimeString = value.ToString("u")};
}
public static implicit operator DateTimeOffset(DateTimeOffsetSurrogate value)
{
return DateTimeOffset.Parse(value.DateTimeString);
}
}
然后像这样注册
RuntimeTypeModel.Default.Add(typeof(DateTimeOffset), false).SetSurrogate(typeof(DateTimeOffsetSurrogate));
这篇关于我可以使用 protobuf-net 序列化任意类型吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!